如何在没有重定向的情况下返回不同的 Razor 页面?

Posted

技术标签:

【中文标题】如何在没有重定向的情况下返回不同的 Razor 页面?【英文标题】:How to return a different Razor Page without redirect? 【发布时间】:2018-11-03 16:21:43 【问题描述】:

我正在将 Asp.Net MVC 应用程序移植到 Razor Pages。

在 MVC 应用程序的一些控制器中,它使用了return View("someOtherView", someModelForOtherView);

如何将其移植到 Razor Pages? 我需要做的是将请求转移到另一个 Razor 页面并将准备好的 PageModel 传递给它(另一个页面不需要执行OnMethod(),只需渲染它的 html. 或者,换句话说,我只需要将应该渲染的模板文件与另一个交换。

我不能使用Redirect,因为不能通过浏览器进行另一次往返。

【问题讨论】:

我在github上开了一个问题github.com/aspnet/Mvc/issues/8002 【参考方案1】:

我怀疑这(很容易)是可能的。从上面 Lerner 链接的 github request 中可以看出,Razor Pages 并不是为此而设计的。

我能够实现的最接近的解决方法是将我的目标 Razor 页面变成一个视图。 (因此,没有代码隐藏。)显然,只有当您的目标页面从未通过 URL 直接访问时才有可能。例如,如果您想重定向到/Pages/MyPage,并且您仍然需要能够访问 url http://example.com/MyPage,这将不起作用。

但是,假设您只需要一个通用错误或状态页面。这些不必通过 URL 直接访问。这很有效。

这是PageModel 上的几个扩展方法,一个接受模型,一个不接受:

public static ViewResult View(this PageModel pageModel, string viewName) 
    return new ViewResult() 
        ViewName = viewName,
        ViewData = pageModel.ViewData,
        TempData = pageModel.TempData
    ;


public static ViewResult View<TModel>(this PageModel pageModel, string viewName, TModel model) 
    var viewDataDictionary = new ViewDataDictionary<TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) 
        Model = model
    ;
    foreach (var kvp in pageModel.ViewData) viewDataDictionary.Add(kvp);

    return new ViewResult 
        ViewName = viewName,
        ViewData = viewDataDictionary,
        TempData = pageModel.TempData
    ;

仅供参考,必须重新创建视图字典的原因是因为您的 pageModel 中的字典将具有特定于当前页面的模型类型,而不是您指向的视图,并且您不能将 ViewDataDictionary 中的模型更改为不同的类型。 MVC 会抱怨并抛出异常。

用法:

public IActionResult OnGet(string id) 
    // check if id is good here     
    if (idIsNoGood) return this.View("InvalidId", new ErrorModel...);
    else 
        return Page();
    

上面将查找InvalidId.cshtml 视图,该视图可以与您的页面位于同一文件夹、根/Pages/ 文件夹或/Pages/Shared/。它仍然会使用您的布局,就像任何其他页面一样。

只要确保您的 cshtml 文件顶部没有 @page 指令即可;这不适用于 Razor 页面,仅适用于视图。

示例 InvalidId.cshtml:

@model MyProject.Models.ErrorModel
<h1>Invalid Request</h1>
<p>@Model.Message</p>

【讨论】:

谢谢 - 你是救命稻草 - 我花了 6 个小时试图解决这个问题,略有不同 - 我有一个需要返回错误 MVC 视图的剃须刀页面 - 你的解决方案适用于此:-)

以上是关于如何在没有重定向的情况下返回不同的 Razor 页面?的主要内容,如果未能解决你的问题,请参考以下文章

在 Razor 页面中重定向到带有 ID 的页面

JSF AJAX和正常重定向登录并返回上一页

如何在 ASP.Net Core Razor 页面上重定向

在不丢失原始数据的情况下重定向回上一页

如何在没有重定向的情况下提交 HTML 表单

在不同情况下使用 Passport.js 更改和保存重定向