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》https://www.devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
翻译:Sweet Tang
本文地址:http://www.cnblogs.com/tdfblog/p/handling-404-not-found-in-asp-net-core.html
欢迎转载,请在明显位置给出出处及链接。
ASP.NET Core 处理 404 Not Found的更多相关文章
- asp.net core 自定义404等友好错误页面
Home控制器里: [Route("Home/Error/{statusCode}")] public IActionResult Error(int statusCode) { ...
- ASP.NET Core 如何实现404错误跳转到主页
假如用户在Web浏览器上敲错了URL,访问了ASP.NET Core站点下一个不存在的URL地址,那么默认情况下ASP.NET Core会返回给浏览器著名的404错误,那么有什么办法可以让ASP.NE ...
- asp.net core WebAPI学习以及 发布(***入门学习)
A asp.net Core 系列[一]——创建Web应用 asp.net Core 系列[二]—— 使用 ASP.NET Core 和 VS2017 for Windows 创建 Web API a ...
- Asp.Net Core 404处理
在使用Asp.Net Core Mvc时 404处理整理如下 一.自带404状态处理 1.控制器视图子弹404视图 NotFoundResult,NotFoundObjectResult // // ...
- ASP.NET Core Kestrel 随机404错误
一.Bug 出现 最近遇到一个很诡异的bug,Visual Studio 2017调试ASP.NET Core 2.2 Web程序的时候,随机性的出现404错误.如下图 事实上这个css文件是存在的, ...
- ASP.NET Core的路由[5]:内联路由约束的检验
当某个请求能够被成功路由的前提是它满足某个Route对象设置的路由规则,具体来说,当前请求的URL不仅需要满足路由模板体现的路径模式,请求还需要满足Route对象的所有约束.路由系统采用IRouteC ...
- ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系
ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...
- ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件
虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件 ...
- 学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?
ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 "通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流 ...
随机推荐
- 转:【深入Java虚拟机】之五:多态性实现机制——静态分派与动态分派
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17965867 方法解析 Class文件的编译过程中不包含传统编译中的连接步骤,一切方法 ...
- 【Beta】阶段 第二次Daily Scrum Meeting
每日任务 1.本次会议为第二次 Meeting会议: 2.本次会议在周二上午9:40,课间休息时间在禹州楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work ite ...
- 团队作业10——beta阶段项目复审
小组的名字和链接 优点 缺点(bug报告) 最终名次 拖鞋大队 基本功能都实现了,符合用户的需求:每次都能按时完成博客,满足题目要求,所以作业完成的也比较优秀.较alpha版本新增了查重自定义的功能, ...
- Swing-setAlignmentX()用法-入门
先看下API: public void setAlignmentX(float alignmentX) 设置垂直对齐方式. 参数: alignmentX - 新的垂直对齐方式 网上关于这个函数的详细情 ...
- 201521123075 《Java程序设计》第5周学习总结
1. 本周学习总结 2. 书面作业 作业参考文件下载 1 .代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分 ...
- 201521123101 《Java程序设计》第3周学习总结
1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...
- 201521123098 JAVA课程设计
1.团队课程设计博客链接 http://www.cnblogs.com/agts/p/7067948.html 2.个人负责模块或任务说明 个人任务:实现初始界面中的登录.注册模块,以及数据库的连接和 ...
- Markdown 模板
一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...
- SharePoint备份文件
stp文件:SharePoint的.stp文件 在做一个和SharePoint有关的项目时,由于对SharePoint的unfamiliar,所以客户发了几个后缀为.stp的文件将我纳闷了半天,不 ...
- Java: 类继承中 super关键字
super 关键字的作用有两个: 1)在子类中调用超类的构造器,完成实例域参数的初始化,调用构造器的语句只能作为另一个构造器(通常指的是子类构造器)的第一条语句出现, 2)在子类中调用超类的方法,如: ...