Asp.Net Core异常处理整理
目前版本是Asp.Net Core v1.1,這個版本的感覺對Http請求中的錯誤處理方便不是很完善。
沒有HttpException異常類,不能在任何的地方自由的拋出對應的異常狀態(tài)。
一、默認的異常處理配置
1.默認配置在StartUp文件的Configure中注冊錯誤處理
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");} }特別說明:
1.env.IsDevelopment() ?用于判斷當前運行環(huán)境是否是測試環(huán)境
2.app.UseDeveloperExceptionPage(); 如果是測試環(huán)境則啟用開發(fā)者異常頁面
開發(fā)者異常頁面
當在Web處理管道放生了一個位置異常時,開發(fā)者異常頁面會顯示有用的調(diào)試信息。頁面包含幾個選項卡顯示Stack、Query、Cookie、Header異常信息。
3.app.UseExceptionHandler("/Home/Error"); 在正式運行環(huán)境中輸出異常的內(nèi)容信息。
4.默認的異常處理對于404沒有處理,如果是404的地址則返回空內(nèi)容。
5.業(yè)務邏輯404的拋出
使用狀態(tài)視圖
public IActionResult Test2() {//手動拋出404 頁面return StatusCode(404, "你要訪問的頁面不存在"); }或者修改相應上下文的狀態(tài)碼
@{//自定義拋出404異常this.Context.Response.StatusCode = 404; } <h1>404狀態(tài)的頁面</h1>二、錯誤處理擴展,使用委托
1.
?
//此處的404頁面,只能用于處理路由中不匹配的404頁面 //如果是程序邏輯中的404不予以處理 //并且對于程序中Exception 也不做處理,直接相應500,內(nèi)容為空 RequestDelegate handler = async context => {var resp = context.Response;if (resp.StatusCode == 404){await resp.WriteAsync($"當前是404頁面,暫時沒有獲取到異常內(nèi)容");} }; app.UseStatusCodePages(builder => {builder.Run(handler); });?
2.
//使用StatusCodePagesMiddleware 指定狀態(tài)對應的顯示頁面 Func<StatusCodeContext, Task> handler = async context => {var resp = context.HttpContext.Response;if (resp.StatusCode == 404){//需要 using Microsoft.AspNetCore.Http;await resp.WriteAsync($"當前是404頁面,暫時沒有獲取到異常內(nèi)容", Encoding.UTF8);}else if (resp.StatusCode == 500){await resp.WriteAsync($"當前是500頁面,暫時沒有獲取到異常內(nèi)容", Encoding.UTF8);} }; app.UseStatusCodePages(handler);?
?
三、錯誤處理擴展,使用自定義擴展類
Asp.Net Core三種呈現(xiàn)錯誤也的方式都可以擴展
1.DeveloperExceptionPageMiddleware中間件的擴展可以自定義開發(fā)者異常頁面,當前略過
2.ExceptionHandlerMiddleware中間件,可以自定義擴展異常處理
示例,處理異常并制定異常的響應頁面
public class ErrorHandlingMiddleware {private RequestDelegate _next;private ExceptionHandlerOptions _options;public ErrorHandlingMiddleware(RequestDelegate next, IOptions<ExceptionHandlerOptions> options){_next = next;_options = options.Value;}public async Task Invoke(HttpContext context){try{await _next(context);}catch{//雖然此處指定500,但是出現(xiàn)異常,再次執(zhí)行異常頁面則響應的是200context.Response.StatusCode = 500;context.Response.Clear();if (_options.ExceptionHandlingPath.HasValue){context.Request.Path = _options.ExceptionHandlingPath;}RequestDelegate handler = _options.ExceptionHandler ?? _next;await handler(context);}} }使用擴展方法為IApplicationBuilder擴展內(nèi)容
public static class ErrorHandlingExtensions {public static IApplicationBuilder UseErrorHandling(this IApplicationBuilder builder, ExceptionHandlerOptions options){return builder.UseMiddleware<ErrorHandlingMiddleware>(Options.Create(options));} }在 Configure中注冊當前錯誤處理
//使用自定義異常處理 app.UseErrorHandling(new ExceptionHandlerOptions() {//注意此處的路徑不能使用~符號ExceptionHandlingPath = "/Home/Error" });3.StatusCodePagesMiddleware中間件可以根據(jù)正常的相應內(nèi)容(沒有拋出異常的情況下) 擴展狀態(tài)相應頁面
public interface IStatusCodePagesFeature {bool Enabled { get; set; } }public class StatusCodePagesFeature : IStatusCodePagesFeature {public bool Enabled { get; set; } = true; } public class StatusCodePagesMiddleware {private RequestDelegate _next;private StatusCodePagesOptions _options;public StatusCodePagesMiddleware(RequestDelegate next,IOptions<StatusCodePagesOptions> options){_next = next;_options = options.Value;}public async Task Invoke(HttpContext context){//可以用于阻止異常處理StatusCodePagesFeature feature = new StatusCodePagesFeature();context.Features.Set<IStatusCodePagesFeature>(feature);await _next(context);HttpResponse response = context.Response;//對于響應的狀態(tài)編碼,返回內(nèi)容//if ((response.StatusCode >= 400 && response.StatusCode <= 599) && !response.ContentLength.HasValue && string.IsNullOrEmpty(response.ContentType))if (response.StatusCode >= 400 && response.StatusCode <= 599 && feature.Enabled){//觸發(fā) 默認處理//await _options.HandleAsync(new StatusCodeContext(context, _options, _next));//對于非異常的頁面,執(zhí)行Clear拋出異常//response.Clear();//response.Body.Seek(0, SeekOrigin.Begin);await response.WriteAsync($"當前HttpCode={response.StatusCode}");}}}使用擴展方法注冊中間件
public static class ErrorHandlingExtensions {//注冊3中處理方式public static IApplicationBuilder UseStatusCodeHandling(this IApplicationBuilder builder){return builder.UseMiddleware<StatusCodePagesMiddleware>();}public static IApplicationBuilder UseStatusCodeHandling(this IApplicationBuilder app, StatusCodePagesOptions options){return app.UseMiddleware<StatusCodePagesMiddleware>(Options.Create(options));}public static IApplicationBuilder UseStatusCodeHandling(this IApplicationBuilder app, Func<StatusCodeContext, Task> handler){return app.UseStatusCodePages(new StatusCodePagesOptions{HandleAsync = handler});} }在Configure中注冊使用
Func<StatusCodeContext, Task> handler = async context => {var resp = context.HttpContext.Response;//在以下的相應數(shù)據(jù)時,會清空原頁面的相應內(nèi)容if (resp.StatusCode == 404){//需要 using Microsoft.AspNetCore.Http;await resp.WriteAsync($"當前是404頁面,暫時沒有獲取到異常內(nèi)容", Encoding.UTF8);}else if (resp.StatusCode == 500){await resp.WriteAsync($"當前是500頁面,暫時沒有獲取到異常內(nèi)容", Encoding.UTF8);} }; app.UseStatusCodeHandling(handler);4.可以在擴展中綜合使用處理,如下示例
public class ErrorHandlingMiddleware {private readonly RequestDelegate next;private ExceptionHandlerOptions _options;public ErrorHandlingMiddleware(RequestDelegate next, IOptions<ExceptionHandlerOptions> options){this.next = next;this._options = options.Value;}public async Task Invoke(HttpContext context){try{await next(context);}catch (Exception ex){var statusCode = context.Response.StatusCode;if (ex is ArgumentException){statusCode = 200;}await HandleExceptionAsync(context, statusCode, ex.Message);}finally{var statusCode = context.Response.StatusCode;var msg = "";if (statusCode == 401){msg = "未授權(quán)";}else if (statusCode == 404){//msg = "未找到服務";//如果是404 返回404頁面if (_options.ExceptionHandlingPath.HasValue){context.Request.Path = _options.ExceptionHandlingPath;}RequestDelegate handler = _options.ExceptionHandler ?? next;await handler(context);}else if (statusCode == 502){msg = "請求錯誤";}else if (statusCode != 200){msg = "未知錯誤";}if (!string.IsNullOrWhiteSpace(msg)){await HandleExceptionAsync(context, statusCode, msg);}}}private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg){var data = new { code = statusCode.ToString(), is_success = false, msg = msg };var result = JsonConvert.SerializeObject(new { data = data });try{//特別說明ContentType屬性在 HttpResponse初始化完成之后就不能修改了//如果試圖修改則拋出異常//異常內(nèi)容:Headers are read-only, response has already started.//context.Response.ContentType = "application/json;charset=utf-8";//特別說明對于準備輸出的Response,執(zhí)行Clear()清空拋出異常//The response cannot be cleared, it has already started sending. context.Response.Clear();//判斷輸出流是否已經(jīng)開始//context.Response.HasStarted }catch (Exception ex){//throw ex; }//清楚已經(jīng)完成的相應內(nèi)容return context.Response.WriteAsync(result);} } View Code原文參考:http://www.cnblogs.com/artech/p/error-handling-in-asp-net-core-1.html
更多:
Restful API 的設計規(guī)范(轉(zhuǎn))
.Net Core配置文件讀取整理
EF Core 1.0 和 SQLServer 2008 分頁的問題
轉(zhuǎn)載于:https://www.cnblogs.com/tianma3798/p/7126372.html
總結(jié)
以上是生活随笔為你收集整理的Asp.Net Core异常处理整理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入学习jQuery鼠标事件
- 下一篇: TRUNCATE,DELETE,DROP