ASP.NET Core应用错误处理之ExceptionHandlerMiddleware中间(3)

public class Program { public static void Main() { new WebHostBuilder() .UseKestrel() .ConfigureServices(svcs => svcs.AddRouting()) .Configure(app => app .UseExceptionHandler(builder => builder.Run(async context => await context.Response.WriteAsync("Error occurred!"))) .Run(Invoke)) .Build() .Run(); } private static Random _random = new Random(); private async static Task Invoke(HttpContext context) { context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue { MaxAge = TimeSpan.FromHours(1) }; if (_random.Next() % 2 == 0) { throw new InvalidOperationException("Manually thrown exception..."); } await context.Response.WriteAsync("Succeed..."); } }

通过调用扩展方法 UseExceptionHandler注册的ExceptionHandlerMiddleware中间件在处理异常时会响应一个内容为“Error occurred!”的字符串。如下所示的两个响应报文分别对应于正常响应和抛出异常的情况,我们会发现程序中设置的缓存报头“Cache-Control: max-age=3600”只会出现在状态码为“200 OK”的响应中。至于状态码为“500 Internal Server Error”的响应中,则会出现三个与缓存相关的报头,它们的目的都会为了禁止缓存(或者指示缓存过期)。

HTTP/1.1 200 OK Date: Sat, 17 Dec 2016 14:39:02 GMT Server: Kestrel Cache-Control: max-age=3600 Content-Length: 10 Succeed... HTTP/1.1 500 Internal Server Error Date: Sat, 17 Dec 2016 14:38:39 GMT Server: Kestrel Cache-Control: no-cache Pragma: no-cache Expires: -1 Content-Length: 15 Error occurred!

ExceptionHandlerMiddleware中间件针对缓存响应报头的清除体现在如下所示的代码片段中。我们可以看出它通过调用HttpResponse的OnStarting方法注册了一个回调(ClearCacheHeaders),上述的这三个缓存报头在这个回调中设置的。除此之外,我们还看到这个回调方法还会清除ETag报头,这也很好理解:由于目标资源没有得到正常的响应,表示资源“签名”的ETag报头自然不应该出现在响应报文中。

public class ExceptionHandlerMiddleware { ... public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { … context.Response.OnStarting(ClearCacheHeaders, context.Response); RequestDelegate handler = _options.ExceptionHandler ?? _next; await handler(context); } } private Task ClearCacheHeaders(object state) { var response = (HttpResponse)state; response.Headers[HeaderNames.CacheControl] = "no-cache"; response.Headers[HeaderNames.Pragma] = "no-cache"; response.Headers[HeaderNames.Expires] = "-1"; response.Headers.Remove(HeaderNames.ETag); return Task.CompletedTask; } }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

您可能感兴趣的文章:

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

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