UseStatusCodePagesWithRedirects 与 UseStatusCodePagesWithReExecute 对比

admin
admin
2021-06-03
分享:

本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP)
本文出自《从零开始学 ASP.NET Core 与 EntityFramework Core》目录
视频课程效果更佳:跨平台开发实战掌握 ASP.NET Core 与 EntityFramework Core

UseStatusCodePagesWithRedirects 与 UseStatusCodePagesWithReExecute 对比

在章节中,我们将讨论 UseStatusCodePagesWithRedirects 和 UseStatusCodePagesWithReExecute 中间件之间的区别。

从最终用户的角度来看,无论您使用哪种中间件组件,产生的结果都没有区别。我们在两种情况下都看到了指定的自定义错误视图。

##UseStatusCodePagesWithRedirects 中间件

app.UseStatusCodePagesWithRedirects("/Error/{0}");

我们之前通过 URLhttp://localhost/market/food发起请求时,由于此 URL 与我们的应用程序中的任何路由都不匹配,因此会引发 404 错误代码。

UseStatusCodePagesWithRedirects 中间件组件会拦截 404 状态代码,顾名思义,它表示发出重定向到指定的错误路径中(在我们的例子中路径为"/Error/404")。

##使用 UseStatusCodePagesWithRedirects 请求处理

如果使用 UseStatusCodePagesWithRedirects,它向http://localhost/market/food发出请求时同样会触发 404 状态代码。

  • StatusCodePagesWithRedirects 中间件拦截此请求,并将其更改为 302,将其指向错误路径(/Error/404)
  • 302 状态代码表示所请求资源的 URL 已被暂时更改,在我们的示例中,它更改为/Error/404
  • 因此,它会发出另一个 GET 请求以满足重定向的请求。
  • 由于发出了重定向,请注意地址栏中的 URL 也从/market/food 更改为/Error/404
  • 请求流会经过 http 管道并由 MVC 中间件处理,最终返回状态代码为 200 ,然后导航到 NotFound 视图中(这意味着请求已成功完成)
  • 对整个请求流程中的浏览器而言,没有 404 错误信息。
  • 如果您仔细观察此请求和响应流,我们在实际发生错误时返回成功状态代码为 200,这在语义上不正确的。

59-1

使用 UseStatusCodePagesWithReExecute 请求处理

如果应用程序使用 UseStatusCodePagesWithReExecute("/Error/{0}")。它向http://localhost/market/food发出请求时同样会触发 404 状态代码。

  • UseStatusCodePagesWithReExecute 中间件拦截 404 状态代码并重新执行将其指向 URL 的管道即我们的(/Error/404)中。
  • 整个请求流经 Http 管道并由 MVC 中间件处理,该中间件返回 NotFound 视图 HTML 的状态代码 依然是 200。
  • 当响应流出到客户端时,它会通过 UseStatusCodePagesWithReExecute 中间件,该中间件会使用 HTML 响应,将 200 状态代码替换为原始的 404 状态代码。
  • 这是一个聪明的中间件。顾名思义,它重新执行管道应该正确的(404)状态代码。它只返回自定义视图(NotFound)
  • 因为它只是重新执行管道而不发出重定向请求,所以我们还在地址栏中保留原始 http://localhost/market/food。它不会从/market/food 更改为/Error/404

59-1

如果您正在使用 UseStatusCodePagesWithReExecute 中间件,则还可以使用 IStatusCodeReExecuteFeature 接口在 ErrorController 中获取原始路径,如下所示。

  public class ErrorController:Controller
    {
        [Route("Error/{statusCode}")]
        public IActionResult HttpStatusCodeHandler(int statusCode)
        {

            var statusCodeResult =
                HttpContext.Features.Get<IStatusCodeReExecuteFeature>();


            switch (statusCode)
            {
                case 404:
                    ViewBag.ErrorMessage = "抱歉,你访问的页面不存在";
                    ViewBag.Path = statusCodeResult.OriginalPath;
                    ViewBag.QS = statusCodeResult.OriginalQueryString;
                    break;
            }

            return View("NotFound");
        }
    }

然后,您可以在自定义错误视图中显示它,如下所示


@{
    ViewBag.Title = "页面不存在";
}

<h1>@ViewBag.ErrorMessage</h1>

<h1>@ViewBag.Path</h1>

<h1>@ViewBag.QS</h1>
<a asp-action="index" asp-controller="home">
    点击此处返回首页
</a>

我们重新运行我们的程序,往 URL 地址中输入 http://localhost:5160/market/food/3?name=apple,得到的返回视图如下:

59-3

  • statusCodeResult.OriginalPath,可以获取我们的 URL 请求信息,

  • statusCodeResult.OriginalQueryString,会获取我们的查询字符串的搜索信息

##文章说明

如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com 保留版权
感谢您对我的支持

##关注微信公众号:角落的白板报

公众号:角落的白板报