(7)ASP.NET Core2.2 中的错误处理
1.前言
ASP.NET Core处理错误环境区分为两种:开发环境和非开发环境。
●开发环境:开发人员异常页。
●非开发环境:异常处理程序页、状态代码页。
在Startup.Configure方法里面我们会看到如下代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { //开发环境 } else { //非开发环境 } }
env.IsDevelopment()是判断应用程序运行是在开发环境还是非开发环境,具体配置在Properties/launchSettings.json,找到ASPNETCORE_ENVIRONMENT属性,默认值是开发环境(Development),具体环境配置知识点后面我们再来学习下。
2.开发人员异常页
向Startup.Configure方法添加代码,以当应用在开发环境中运行时启用此页:
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
开发人员异常页仅当应用程序在开发环境中运行时才会启用,而且调用UseDeveloperExceptionPage要配置于任何要捕获其异常的中间件前面。
该页包括关于异常和请求的以下信息:
●堆栈跟踪
●查询字符串参数(如果有)
●Cookie(如果有)
●request header
3.异常处理程序页
在下面的示例中,UseExceptionHandler 在非开发环境中添加异常处理中间件:
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); }
Razor Pages应用模板提供“页面”文件夹中的Error页(.cshtml)和PageModel类(ErrorModel)。 对于MVC应用,项目模板包括Error操作方法和Error视图。操作方法如下:
[AllowAnonymous] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); }
不要使用HTTP方法属性(如HttpGet)修饰错误处理程序操作方法,因为会阻止某些请求访问的方法。同时最好允许匿名访问方法,以便未经身份验证的用户能够接收错误视图。
UseExceptionHandler中间还可以使用lambda进行异常处理:
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { context.Response.StatusCode = 500; context.Response.ContentType = "text/html"; await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n"); await context.Response.WriteAsync("ERROR!<br><br>\r\n"); var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); // Use exceptionHandlerPathFeature to process the exception (for example, // logging), but do NOT expose sensitive error information directly to // the client. if (exceptionHandlerPathFeature?.Error is FileNotFoundException) { await context.Response.WriteAsync("File error thrown!<br><br>\r\n"); } await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n"); await context.Response.WriteAsync("</body></html>\r\n"); await context.Response.WriteAsync(new string(' ', 512)); // IE padding }); }); app.UseHsts(); }
4.状态代码页
一般情况下,ASP.NET Core应用程序不会为HTTP状态代码(如“404-未找到”)提供状态代码页的。但若要提供状态代码页,可以使用状态代码页中间件。
4.1 UseStatusCodePages中间件
若要启用常见错误状态代码的默认纯文本处理程序,请在Startup.Configure方法中调用 UseStatusCodePages:
app.UseStatusCodePages();
而这里有一点要注意的是,调用UseStatusCodePages中间件要在例如静态文件中间件和 MVC中间件等中间件前面调用:
app.UseStatusCodePages(); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
下面通过运行应用程序在浏览器地址栏上输入一个不存在地址看看配置该中间件后的效果:
很显然当我们输入一个不存在地址之后就会打开一个处理错误的状态代码页。
UseStatusCodePages中间件还有两种重载使用方法,具体运行效果就不一一截图了,大家自行测试。
●包含格式字符串的 UseStatusCodePages:
app.UseStatusCodePages("text/plain", "Status code page, status code: {0}");
●包含lambda的UseStatusCodePages:
app.UseStatusCodePages(async context => { context.HttpContext.Response.ContentType = "text/plain"; await context.HttpContext.Response.WriteAsync( "Status code page, status code: " + context.HttpContext.Response.StatusCode); });
4.2 UseStatusCodePagesWithRedirect中间件
●向客户端发送“302 - 已找到”状态代码。
●将客户端重定向到URL模板中的位置。
下面我们在Startup.Configure方法中调用UseStatusCodePagesWithRedirect:
app.UseStatusCodePagesWithRedirects("/Error/{0}");
运行应用程序在浏览器上输入不存在地址https://localhost:44353/1看看配置该中间件后的效果,你会发觉当我们输入上述地址后会跳转到https://localhost:44353/Error/404链接去了,并显示:
这就说明白当我们输入一个不存在地址之后会重定向中间件设置的地址页面去了。
参考文献:
处理 ASP.NET Core 中的错误