ASP.NET Core应用错误处理之三种呈现错误页面的方(2)

new WebHostBuilder() .UseStartup<Startup>() … public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } } }

二、显示定制异常页面

DeveloperExceptionPageMiddleware中间件通过将异常详细信息和基于当前请求的内容直接呈现在错误页面中,这为开发人员的纠错诊断提供了极大的便利。但是在生产环境下,我们倾向于为最终的用户呈现一个定制的错误页面,而这可以通过注册另一个名为ExceptionHandlerMiddleware的中间件来实现。顾名思义,这个中间件旨在提供一个异常处理器(Exception Handler)来处理抛出的异常。实际上这个所谓的异常处理器就是一个类型为RequestDelegate的委托对象,ExceptionHandlerMiddleware中间件捕捉到抛出的异常后利用它来响应当前的请求。

还是以上面创建的这个总是会抛出一个 InvalidOperationException异常的应用为例。我们按照如下的形式调用ApplicationBuilder的扩展方法UseExceptionHandler注册了上述的这个ExceptionHandlerMiddleware中间件。这个扩展方法具有一个ExceptionHandlerOptions类型的参数,它的ExceptionHandler属性返回的就是这个作为异常处理器的RequestDelegate对象。

public class Program { public static void Main() { RequestDelegate handler = async context => await context.Response.WriteAsync("Unhandled exception occurred!"); new WebHostBuilder() .UseKestrel() .Configure(app => app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = handler}) .Run(context => Task.FromException(new InvalidOperationException("Manually thrown exception...")))) .Build() .Run(); } }

如上面的代码片段所示,这个作为异常处理器的RequestDelegate仅仅是将一个简单的错误消息(“Unhandled exception occurred!”)作为响应的内容。当我们利用浏览器访问该应用的时候,这个定制的错误消息将会以如图4所示的形式直接呈现在浏览器上。

ASP.NET Core应用错误处理之三种呈现错误页面的方

最终作为异常处理器的是一个类型为RequestDelegate的委托对象,而ApplicationBuilder具有创建这个委托对象的能力。具体来说,我们可以根据异常处理的需要将相应的中间件注册到某个ApplicationBuilder对象上,并最终利用这个ApplicationBuilder根据注册的中间件创建出作为异常处理器的RequestDelegate对象。 如果异常处理需要通过一个或者多个中间件来完成,我们可以按照如下的形式调用另一个UseExceptionHandler方法重载。这个方法的参数类型为Action<IApplicationBuilder>,我们调用它的Run方法注册了一个中间件来响应一个简单的错误消息。

public class Program { public static void Main() { new WebHostBuilder() .UseKestrel() .Configure(app => app.UseExceptionHandler(builder=>builder.Run(async context => await context.Response.WriteAsync("Unhandled exception occurred!"))) .Run(context => Task.FromException(new InvalidOperationException("Manually thrown exception...")))) .Build() .Run(); } }

上面这两种异常处理的形式都体现在提供一个RequestDelegate的委托对象来处理抛出的异常并完成最终的响应。如果应用已经设置了一个错误页面,并且这个错误页面具有一个固定的路径,那么我们在进行异常处理的时候就没有必要提供这个RequestDelegate对象,而只需要重定向到错误页面指向的路径即可。这种采用服务端重定向的异常处理方式可以采用如下的形式调用另一个UseExceptionHandler方法重载来完成,这个方法的参数表示的就是重定向的目标路径(“/error”),我们针对这个路径注册了一个路由来响应定制的错误消息。

public class Program { public static void Main() { new WebHostBuilder() .UseKestrel() .ConfigureServices(svcs=>svcs.AddRouting()) .Configure(app => app .UseExceptionHandler("/error") .UseRouter(builder=>builder.MapRoute("error", async context => await context.Response.WriteAsync("Unhandled exception occurred!"))) .Run(context => Task.FromException(new InvalidOperationException("Manually thrown exception...")))) .Build() .Run(); } }

三、针对响应状态码定制错误页面

由于Web应用采用HTTP通信协议,所以我们应该尽可能低迎合HTTP标准并将定义在协议规范中的语义应用到应用中。对于异常或者错误的语义表达在HTTP协议层面主要体现在响应报文的状态码上,具体来说HTTP通信的错误大体分为如下两种类型:

客户端错误:表示因客户端提供不正确的请求信息而导致服务器不能正常处理请求,响应状态码范围在400~499之间。

服务端错误:表示服务器在处理请求过程中因自身的问题而发生错误,响应状态码在500~509之间。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsjzj.html