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

时间:2018-05-24 12:23:20

标签: razor-pages

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

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

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

我无法使用Redirect,因为浏览器不得再进行另一次往返。

1 个答案:

答案 0 :(得分:1)

我怀疑这是(轻松)可能的。从上面Lerner链接的github request可以看出,Razor Pages并非旨在做到这一点。

我能够实现的最接近的解决方法是将目标Razor Page转换为View。 (因此,没有任何代码隐藏。)显然,只有在您的目标页面从不直接通过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页面,仅适用于View。

示例InvalidId.cshtml:

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