失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 如何在 ASP.NET Core 中实现全局异常拦截

如何在 ASP.NET Core 中实现全局异常拦截

时间:2022-07-26 07:17:27

相关推荐

如何在 ASP.NET Core 中实现全局异常拦截

异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 Core MVC 中实现全局异常处理,我会用一些 样例代码 和 截图 来说明这些概念。

全局异常处理

其实在 Core MVC 框架中已经有了全局异常处理的机制,你可以在一个中心化的地方使用全局异常处理中间件来进行异常拦截,如果不用这种中心化方式的话,你就只能在 Controller 或者 Action 作用域上单独处理,这会导致异常处理代码零散在项目各处,不好维护也特别麻烦,不是吗?

第二种处理 全局异常 的做法就是使用 exception filter,在本篇中,我准备跟大家聊一聊全局异常处理中间件UseExceptionHandler方法来管控异常。

使用 UseExceptionHandler 扩展方法

UseExceptionHandler 扩展方法能够将 ExceptionHandler 中间件注册到 Core 的请求处理管道中,然后在 IExceptionHandlerFeature 接口的实例中获取 异常对象,下面的代码片段展示了如何使用 UseExceptionHandler 方法来截获全局异常。

publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){app.UseExceptionHandler(builder=>{builder.Run(asynccontext=>{context.Response.StatusCode=(int)HttpStatusCode.InternalServerError;context.Response.ContentType="application/json";varexception=context.Features.Get<IExceptionHandlerFeature>();if(exception!=null){varerror=newErrorMessage(){Stacktrace=exception.Error.StackTrace,Message=exception.Error.Message};varerrObj=JsonConvert.SerializeObject(error);awaitcontext.Response.WriteAsync(errObj).ConfigureAwait(false);}});});app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints=>{endpoints.MapControllerRoute(name:"default",pattern:"{controller=Home}/{action=Index}/{id?}");});}

下面是代码中引用的 ErrorMessage 类的定义。

publicclassErrorMessage{publicstringMessage{get;set;}publicstringStacktrace{get;set;}}

配置 全局异常中间件

大家都知道, Core MVC 项目中都会有一个 Startup.cs 文件,可以在 Configure 方法下配置全局异常拦截中间件代码,如下所示:

publicvoidConfigure(IApplicationBuilderapp,IHostingEnvironmentenv){if(env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");}app.UseStaticFiles();app.UseCookiePolicy();app.UseMvc(routes=>{routes.MapRoute(name:"default",template:"{controller=Home}/{action=Index}/{id?}");});}

可以着重看一下上面的app.UseExceptionHandler("/Error");,这里的 UseExceptionHandler 实现了 pipeline 注册,一旦应用程序出现了未处理异常,那么会自动将 用户 导向/Error页面。

你可以用 UseStatusCodePagesWithReExecute 扩展方法给 pipeline 添加一些状态码页面,这是什么意思呢?其实也就是 http 500 导向 500 页面, http 404 导向 404 页面,下面的代码片段展示了修改后的 Configure 方法代码。

publicvoidConfigure(IApplicationBuilderapp,IHostingEnvironmentenv){if(env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");app.UseStatusCodePagesWithReExecute("/Error/NotFound/{0}");}//Othercode}

使用 ErrorController

在 HomeController 下有一个专门处理错误的 action 方法,这里我们不使用这个 action,你可以把它删掉,接下来我准备定义一个专门的 ErrorController,里面包含了一个路由为/Error的 action 方法。

publicclassErrorController:Controller{[HttpGet("/Error")]publicIActionResultIndex(){IExceptionHandlerPathFeatureiExceptionHandlerFeature=HttpContext.Features.Get<IExceptionHandlerPathFeature>();if(iExceptionHandlerFeature!=null){stringpath=iExceptionHandlerFeature.Path;Exceptionexception=iExceptionHandlerFeature.Error;//WritecodeheretologtheexceptiondetailsreturnView("Error",iExceptionHandlerFeature);}returnView();}[HttpGet("/Error/NotFound/{statusCode}")]publicIActionResultNotFound(intstatusCode){variStatusCodeReExecuteFeature=HttpContext.Features.Get<IStatusCodeReExecuteFeature>();returnView("NotFound",iStatusCodeReExecuteFeature.OriginalPath);}}

你可以用IExceptionHandlerPathFeature来获取异常相关信息,也可以用IStatusCodeReExecuteFeature来获取 http 404 异常时当时的请求路径,对了,要想用上IExceptionHandlerPathFeatureIStatusCodeReExecuteFeature,要记得在 nuget 上安装了 Microsoft.AspNetCore.Diagnostics 包,下面的代码展示了如何获取异常发生时刻的路由地址。

stringroute=iExceptionHandlerFeature.Path;

如果想获取异常的详细信息,可以使用如下语句。

varexception=HttpContext.Features.Get<IExceptionHandlerPathFeature>();

一旦获取了这个路由地址和异常的详细信息,就可以将它记录到你的日志文件中,可供后续仔细分析。

使用 View 展示错误信息

可以创建一个 View 来展示出现的错误信息,下面时Error ViewPage的详细代码。

@modelMicrosoft.AspNetCore.Diagnostics.IExceptionHandlerFeature@{ViewData["Title"]="Index";Layout="~/Views/Shared/_Layout.cshtml";}<divclass="row"><divclass="text-danger"><h3>Error:@Model.Error.Message</h3></div></div><divclass="row"><divclass="col-12"><p>@Model.Error.StackTrace</p><p>@Model.Error.InnerException</p></div></div>

下面是 NotFound 页面的 代码

@modelstring@{ViewData["Title"]="NotFound";Layout="~/Views/Shared/_Layout.cshtml";}<h1class="text-danger">Error:TherequestedURL@Modelwasnotfound!</h1><hr/>

现在可以把程序跑起来了,你会看到如下的错误信息。

如果你尝试打开一个不存在的页面, 会自动跳转到ErrorController.NotFound所包装的 404 描述信息。

Core 中内置了 全局异常处理,你可以利用这项技术在一个集中化的地方去截获你应用程序中的所有异常信息,当然你也可以基于环境的不同采取不用的异常处理措施,比如说:开发环境,测试环境,生产环境 等等。

译文链接:/article/3435771/how-to-implement-global-exception-handling-in-aspnet-core-mvc.html

如果觉得《如何在 ASP.NET Core 中实现全局异常拦截》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。