.net core異常中間件的使用
正文
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
這樣寫入中間件哈,那么在env環(huán)境下就會(huì)去執(zhí)行UseDeveloperExceptionPage。
public static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } return app.UseMiddleware<DeveloperExceptionPageMiddleware>(); }
那么我們應(yīng)該去看DeveloperExceptionPageMiddleware中間件哈。
那么這里介紹它是如何能夠捕獲其他中間件的異常的哈。
里面的invoke:
其實(shí)它的操作是很簡(jiǎn)單的,直接在外面套了try catch。
里面的異常處理怎么處理的可以直接去看DeveloperExceptionPageMiddleware 中間件,里面的操作也比較簡(jiǎn)單處理。
測(cè)試:
[HttpGet] public int GetService([FromServices]ISelfService selfService) { throw new System.Exception("錯(cuò)誤"); return 1; }
結(jié)果:
因?yàn)樯厦嬲f(shuō)了,這個(gè)是dev環(huán)境下,那么生產(chǎn)環(huán)境不能直接給用戶看到錯(cuò)誤信息。
正式環(huán)境:
app.UseExceptionHandler("/error");
將錯(cuò)誤轉(zhuǎn)移到/error 處理。具體UseExceptionHandler細(xì)節(jié)篇里面介紹,有許多可以借鑒的地方。
[ApiController] [Route("[controller]")] public class ErrorController : Controller { public ILogger<ErrorController> _logger; public ErrorController(ILogger<ErrorController> logger) { this._logger = logger; } public IActionResult Index() { var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>(); var ex = exceptionHandlerPathFeature?.Error; var knownException = ex as IKnownException; if (knownException == null) { _logger.LogError(ex, ex.Message); knownException = KnownException.Unknow; } else { knownException = KnownException.FromKnowException(knowException); } return View(knownException); } }
視圖:
<html> <head> </head> <body> <div> 錯(cuò)誤碼: @Model.ErrorCode </div> <div> 錯(cuò)誤信息: @Model.Message </div> </body> </html>
IKnownException:
public interface IKnownException { public string Message { get; } public int ErrorCode { get; } public object[] ErrorData { get; } }
KnownException:
public class KnownException : IKnownException { public string Message { get; private set; } public int ErrorCode { get; private set; } public object[] ErrorData { get; private set; } public readonly static IKnownException Unknow = new KnownException { Message = "未知錯(cuò)誤", ErrorCode = 99 }; public static IKnownException FromKnowException(IKnownException Exception) { return new KnownException{Message = Exception.Message, ErrorCode = Exception.ErrorCode, ErrorData = Exception.ErrorData}; } }
測(cè)試1:
[HttpGet] public int GetService([FromServices]ISelfService selfService) { throw new System.Exception("錯(cuò)誤"); return 1; }
這種屬于未知異常,結(jié)果:
現(xiàn)在弄一個(gè)支付異常:
public class PayErrorException : Exception, IKnownException { public PayErrorException(string message, int errorCode, params object[] errorData): base(message) { this.ErrorCode = errorCode; this.ErrorData = errorData; } public int ErrorCode { get;private set; } public object[] ErrorData { get;private set; } }
測(cè)試2:
[HttpGet] public int GetService([FromServices]ISelfService selfService) { throw new PayErrorException("支付錯(cuò)誤",405,null); return 1; }
將異常處理放入到中間件分支中。
app.UseExceptionHandler(errApp => { errApp.Run(async context => { var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); IKnownException knownException = exceptionHandlerPathFeature.Error as IKnownException; if (knownException == null) { var logger = context.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>(); logger.LogError(exceptionHandlerPathFeature.Error, exceptionHandlerPathFeature.Error.Message); knownException = KnownException.Unknown; context.Response.StatusCode = StatusCodes.Status500InternalServerError; } else { knownException = KnownException.FromKnownException(knownException); context.Response.StatusCode = StatusCodes.Status200OK; } var jsonOptions = context.RequestServices.GetService<IOptions<JsonOptions>>(); context.Response.ContentType = "application/json; charset=utf-8"; await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(knownException, jsonOptions.Value.JsonSerializerOptions)); }); });
效果一樣就不演示了。如果是已知異常錯(cuò)誤碼應(yīng)該為200,一個(gè)是500異常是系統(tǒng)無(wú)法處理,系統(tǒng)錯(cuò)誤,但是已知錯(cuò)誤是屬于系統(tǒng)正常處理。另一個(gè)是監(jiān)控系統(tǒng),認(rèn)為報(bào)500錯(cuò)誤,是會(huì)持續(xù)放出系統(tǒng)警告。
還有一種局部異常,只在mvc中生效,而不是全局生效:
public class MyExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { IKnownException knownException = context.Exception as IKnownException; if (knownException == null) { var logger = context.HttpContext.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>(); logger.LogError(context.Exception, context.Exception.Message); knownException = KnownException.Unknown; context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; } else { knownException = KnownException.FromKnownException(knownException); context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; } context.Result = new JsonResult(knownException) { ContentType = "application/json; charset=utf-8" }; } }
在mvc 中注冊(cè):
services.AddMvc(mvcOptions => { mvcOptions.Filters.Add<MyExceptionFilter>(); }).AddJsonOptions(jsonOptions => { jsonOptions.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping; });
最后介紹一種,只作用于某個(gè)控制器,或者action:
public class MyExceptionFilterAttribute : ExceptionFilterAttribute { public override void OnException(ExceptionContext context) { IKnownException knownException = context.Exception as IKnownException; if (knownException == null) { var logger = context.HttpContext.RequestServices.GetService<ILogger<MyExceptionFilterAttribute>>(); logger.LogError(context.Exception, context.Exception.Message); knownException = KnownException.Unknown; context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; } else { knownException = KnownException.FromKnownException(knownException); context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; } context.Result = new JsonResult(knownException) { ContentType = "application/json; charset=utf-8" }; } }
查看一下ExceptionFilterAttribute頭部:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public abstract class ExceptionFilterAttribute : Attribute, IAsyncExceptionFilter, IExceptionFilter, IOrderedFilter
上面標(biāo)志了可以放于類上也可以放于方法上。所以可以放至在controller上,也可以action上,看需求了。
結(jié)
以上就是.net core異常中間件的使用的詳細(xì)內(nèi)容,更多關(guān)于.net core異常中間件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- ASP.NET Core 應(yīng)用程序中的靜態(tài)文件中間件的實(shí)現(xiàn)
- .Net Core中間件之靜態(tài)文件(StaticFiles)示例詳解
- ASP.NET Core中間件初始化的實(shí)現(xiàn)
- 詳解ASP.NET Core 中基于工廠的中間件激活的實(shí)現(xiàn)方法
- 在 asp.net core 的中間件中返回具體的頁(yè)面的實(shí)現(xiàn)方法
- ASP.NET Core自定義中間件如何讀取Request.Body與Response.Body的內(nèi)容詳解
- .net core webapi通過(guò)中間件獲取請(qǐng)求和響應(yīng)內(nèi)容的方法
- 利用.net core實(shí)現(xiàn)反向代理中間件的方法
- 如何給asp.net core寫個(gè)中間件記錄接口耗時(shí)
- ASP.NET Core中間件計(jì)算Http請(qǐng)求時(shí)間示例詳解
- ASP.NET Core應(yīng)用錯(cuò)誤處理之ExceptionHandlerMiddleware中間件呈現(xiàn)“定制化錯(cuò)誤頁(yè)面”
- .net core靜態(tài)中間件的使用
相關(guān)文章
asp.net頁(yè)面SqlCacheDependency緩存實(shí)例
這篇文章主要介紹了asp.net頁(yè)面SqlCacheDependency緩存實(shí)例,以一個(gè)完整實(shí)例來(lái)展現(xiàn)asp.net中緩存技術(shù)的使用方法,需要的朋友可以參考下2014-08-08使用Visual Studio 2017寫靜態(tài)庫(kù)
這篇文章主要為大家詳細(xì)介紹了Visual Studio2017寫靜態(tài)庫(kù)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Asp.net移除Server,X-Powered-By和X-AspNet-Version頭
這篇文章主要介紹了Asp.net移除Server,?X-Powered-By,?和X-AspNet-Version頭,移除X-AspNet-Version很簡(jiǎn)單,只需要在Web.config中增加相應(yīng)配置節(jié),感興趣的朋友一起看看吧2024-02-02關(guān)于有些Asp.net項(xiàng)目發(fā)布后出現(xiàn)網(wǎng)址亂碼的解決方法
最近在部署一個(gè)網(wǎng)站,net2.0開發(fā)的,但是遇到一個(gè)很奇怪的問(wèn)題。2011-07-07ASP.NET?MVC5網(wǎng)站開發(fā)顯示文章列表(九)
顯示文章列表分兩塊,管理員可以顯示全部文章列表,一般用戶只顯示自己的文章列表。文章列表的顯示采用easyui-datagrid,后臺(tái)需要與之對(duì)應(yīng)的action返回json類型數(shù)據(jù),感興趣的小伙伴們可以參考一下2015-09-09ASP.NET 圖片防盜鏈的實(shí)現(xiàn)原理分析
防盜鏈的原理,從圖片請(qǐng)求的URL地址上判斷是否是我們自己網(wǎng)站上的域名,如果不是,恭喜,你的圖片已經(jīng)被盜鏈了!2010-01-01