详解ASP.NET Core 处理 404 Not Found

 更新时间:2022年02月22日 11:02:39   作者:Sweet-Tang  
这篇文章主要介绍了详解ASP.NET Core 处理 404 Not Found,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

问题

在没有修改任何配置的情况下,这是用户使用 Chrome 访问不存在的URL时会看到的内容:

幸运的是,处理错误状态代码非常简单,我们将在下面介绍三种技术。

解决方案

在以前的ASP.NET MVC版本中,主要在 web.config 中处理404错误的。

您可能记得在 <customErrors> 节点中配置ASP.NET管道处理404错误,以及在低版本的IIS中通过 <httpErrors> 节点处理 404错误。好像有点混乱。

在.Net Core中,情况就不同了,没有必要使用XML配置(尽管如果您是通过IIS代理,您仍然可以在web.config中使用 httpErrors,并且您真的想这样吗:-))。

在处理 not-found 错误时,我们需要处理两种不同的情况。

URL与任何路由不匹配的情况。在这种情况下,如果我们无法确定用户正在访问什么,我们需要返回一个通用的未找到的页面。有两种常见的处理方法,但首先我们将讨论第二种情况。URL与路由匹配的情况,但是一个或多个参数无效,我们可以用自定义视图来解决这个问题。

自定义视图

这种情况的一个例子是具有无效或过期ID的产品页面。在这里,我们知道用户正在查看产品,而不是返回通用错误,我们可以更友好的页面,返回自定义未找到产品的的页面。这仍然需要返回404状态代码,但是使用不通用的页面,同时也可以向用户显示类似或受欢迎的产品。

处理这些情况是非常琐碎,我们需要做的是在返回我们的自定义视图之前设置状态代码:

  public async Task<IActionResult> GetProduct(int id)
  {
    var viewModel = await _db.Get<Product,GetProductViewModel>(id);
  
    if (viewModel == null)
    {
      Response.StatusCode = 404;
      return View("ProductNotFound");
    }
  
    return View(viewModel);
  }

当然,您可能更喜欢将其包装成自定义ActionResult:

  public class NotFoundViewResult : ViewResult
  {
    public NotFoundViewResult(string viewName)      
    {
      ViewName = viewName;
      StatusCode = (int)HttpStatusCode.NotFound;
    }
  }

这简化了我们的Action:

  public async Task<IActionResult> GetProduct(int id)
  {
    var viewModel = await _db.Get<Product,GetProductViewModel>(id);
  
    if (viewModel == null)
    {
      return new NotFoundViewResult("ProductNotFound");
    }
  
    return View(viewModel);
  }

这个简单的技术涵盖了特定的404页,现在来看看通用的404错误,我们无法弄清楚用户想要查看的内容。

通配路由

在先前版本的MVC,创建一个通配符路由来处理,在.NET Core中,也可以使用相同的方式。这个方式是,您有一个通配符路由,它会接收任何其它路由尚未处理的URL。使用特性路由,方式如下:

  [Route("{*url}", Order = 999)]
  public IActionResult CatchAll()
  {
    Response.StatusCode = 404;
    return View();
  }

重要的是指定顺序,以确保其它路由优先。

一个通配符路由的方式非常不错,但它不是.NET Core中的首选。虽然全部路由将处理404,但下一个方式将处理任何非成功状态代码,以便您可以执行以下Action(可能在生产中的Action过滤器中):
 

  public async Task<IActionResult> GetProduct(int id)
  {
    ...
  
    if (RequiresThrottling())
    {
      return new StatusCodeResult(429)
    }
  
    if (!HasPermission(id))
    {
      return Forbid();
    }
  
    ...
  }

StatusCodePagesWithReExecute方法 中件间

UseStatusCodePagesWithReExecute使用了一个非常聪明的中间件(StatusCodePagesMiddleware),在未输出响应前,它能处理非成功状态代码。这意味着如果您使用上面详细描述的自定义视图技术,则404状态代码将不会被中间件处理(这正是我们想要的)。

当从内部中间件组件返回错误代码(如404)时,UseStatusCodePagesWithReExecute允许您执行另一个控制器Action来处理状态代码。

您可以在startup.cs中使用一行代码将其添加到管道中:

  app.UseStatusCodePagesWithReExecute("/error/{0}");
  ...
  app.UseMvc();

中间件定义的顺序很重要,您需要确保在可能返回错误代码的任何中间件(如MVC中间件)之前注册StatusCodeWithReExecute

您可以指定一个固定路径来执行或使用状态代码值的占位符,如上所述。

您还可以指向静态页面(假设您已经具有StaticFileMiddleware中间件)和控制器Action。

在这个例子中,我们有一个单独的Action处理404。任何其它非成功状态代码,使用 Error Action。

  [Route("error/404")]
  public IActionResult Error404()
  {
    return View();
  }
  
  [Route("error/{code:int}")]
  public IActionResult Error(int code)
  {
    // handle different codes or just return the default error view
    return View();
  }

显然,您可以根据您的需要量身定制。例如,如果您正在使用上一节所示的请求限制,那么您可以返回一个解释为什么请求失败的429页面。

总结

处理404页面的具体问题最好用自定义视图来处理,并设置状态代码(直接或通过自定义操作结果)。

通过使用StatusCodePagesMiddleware中间件,可以非常容易地处理通用404错误(或实际上是任何非成功状态代码)。一般来说,这两种技术是在ASP.NET Core中处理非成功HTTP状态代码的首选方法。

原文:《Handling 404 Not Found in Asp.Net Core

翻译:Sweet Tang

相关文章

  • WPF的数据绑定详细介绍

    WPF的数据绑定详细介绍

    数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程。 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改。 数据绑定可能还意味着如果视觉元素中数据的外部表现形式发生更改,则基础数据可以自动更新以反映更改。
    2013-03-03
  • ASP.NET在IIS上注册报0x800702e4错误解决方法

    ASP.NET在IIS上注册报0x800702e4错误解决方法

    报一个0x800702e4 请求的操作需要提升的错误。解决的方法和前面大同小异,给这个aspnet_regiis.exe创建一个快捷方式,给它的目标后面加上 一个-i,再右击这个快捷方式,以管理员身份运行,就行了
    2012-08-08
  • .NET使用Moq进行单元测试

    .NET使用Moq进行单元测试

    这篇文章介绍了.NET使用Moq进行单元测试的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • C#中Dictionary几种遍历的实现代码

    C#中Dictionary几种遍历的实现代码

    C#中Dictionary几种遍历的实现代码,需要的朋友可以参考一下
    2013-02-02
  • .Net Core和jexus配置HTTPS服务方法

    .Net Core和jexus配置HTTPS服务方法

    下面小编就为大家分享一篇.Net Core和jexus配置HTTPS服务方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 注册页实现激活邮箱验证(asp.net c#)

    注册页实现激活邮箱验证(asp.net c#)

    在填写注册提交后,大一点的网站会有邮箱激活验证这一步,本文也是实现了一下,感兴趣的朋友可以参考下哈,希望可以帮助到你
    2013-04-04
  • .NET Core配置多环境的方法步骤

    .NET Core配置多环境的方法步骤

    配置多环境是日常开发经常需要用到的操作,实现多环境配置后可以规避生产测试环境混合带来的麻烦和风险,这篇文章主要介绍了.NET Core配置多环境的方法步骤,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • ASP.NET从客户端中检测到有潜在危险的request.form值的3种解决方法

    ASP.NET从客户端中检测到有潜在危险的request.form值的3种解决方法

    这篇文章主要介绍了ASP.NET从客户端中检测到有潜在危险的request.form值的3种解决方法,这是ASP.NET开发中一个比较常见的经典的问题,需要的朋友可以参考下
    2015-01-01
  • 告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)

    告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)

    说起ADO.NET,就扯上了数据库访问类库了,现在的每个项目的数据库访问类应该说都很强的了,经常就听到说我的我们的数据库访问类怎么怎么强大而且支持多数据库,现在的大家做的项目里用的数据库访问类库我想也都是支持多数据库吧,支持到什么程度我就不知道了
    2009-11-11
  • VS初始化命令 ASP.NET常用技巧

    VS初始化命令 ASP.NET常用技巧

    此命令会运行几分钟时间,与此同时,Visual Studio 清除设置并将其自身重置到其最初的状态。
    2011-03-03

最新评论