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

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

全局异常处理

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

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

使用 UseExceptionHandler 扩展方法

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

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.UseExceptionHandler(builder =>{builder.Run(async context =>{context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;context.Response.ContentType = "application/json";var exception = context.Features.Get<IExceptionHandlerFeature>();if (exception != null){var error = new ErrorMessage(){Stacktrace = exception.Error.StackTrace,Message = exception.Error.Message};var errObj = JsonConvert.SerializeObject(error);await context.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 类的定义。

public class ErrorMessage{public string Message { get; set; }public string Stacktrace { get; set; }}

配置 全局异常中间件

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

public void Configure(IApplicationBuilder app, IHostingEnvironment env){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 方法代码。

public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");app.UseStatusCodePagesWithReExecute("/Error/NotFound/{0}");}//Other code}

使用 ErrorController

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

public class ErrorController : Controller{[HttpGet("/Error")]public IActionResult Index(){IExceptionHandlerPathFeature iExceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();if (iExceptionHandlerFeature != null){string path = iExceptionHandlerFeature.Path;Exception exception = iExceptionHandlerFeature.Error;//Write code here to log the exception detailsreturn View("Error",iExceptionHandlerFeature);}                return View();}[HttpGet("/Error/NotFound/{statusCode}")]public IActionResult NotFound(int statusCode){var iStatusCodeReExecuteFeature =HttpContext.Features.Get<IStatusCodeReExecuteFeature>();return View("NotFound",iStatusCodeReExecuteFeature.OriginalPath);}}

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


string route = iExceptionHandlerFeature.Path;

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


var exception = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

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

使用 View 展示错误信息

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


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

下面是 NotFound 页面的 代码


@model string
@{ViewData["Title"] = "NotFound";Layout = "~/Views/Shared/_Layout.cshtml";
}<h1 class="text-danger">Error: The requested URL @Model was not found!</h1>
<hr />

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306402.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法题目——被围绕的区域(dfs,bfs)

leetcode.130被围绕的区域 dfs解法: 深度优先遍历: 思路: 读取数据后 1.先将数据的四周进行bfs算法(因为只有与外围接触的点,才能不被包围) 算法执行中时,递归看看该点的上下左右有没有是O的,如果是O则标记为A 2.循环完四周之后,将数据中的O全部换成X,将全部的A换成O即得…

qt 从文件中读出数据显示在表格中_QT中有什么控件可以实现向excel的表格显示,qt数据存储到Excel表格...

QT 如何读取大数据量的Excel文件&#xff1f;貌似Excel最多只有1048576行&#xff0c;你这150万行我不知道是怎么放到一个表里面的。数据100多玩行你可以将数据存放在Access或者其他的数据库中或许会比较好一点。QT中有什么控件可以实现向excel的表格显示QTableWidgetQTableVie…

[Windows] 在 Microsoft Docs 网站中挖掘 MVVM 的各种学习资源

最近写了一些 MVVM 框架的文章&#xff0c;翻了一些 Microsoft Docs 的文档&#xff0c;顺便就对 MVVM 本身来了兴致&#xff0c;想看看更多当年相关的文档。在 MVVM 出现后十多年&#xff0c;我在不同的场合见到过多种 MVVM 的实现方式&#xff0c;也看到过各种 MVVM 框架的多…

算法题目——岛屿数量(bfs dfs)

题目链接:leetcode.200岛屿数量 dfs 重点:路过过的点做新标记 ,以防止重复路过 思路: 数据读取完成后 1.对所有数据进行一次循环 2.在循环内部,如果元素为‘1’则进入dfs算法 3.在深度优先遍历中,先将该元素标记为‘0’,在查看它的上下左右元素是否为‘1’,是‘1’则进…

注意| .NET开发者大会防疫须知 !

2020年12月19-20日中国.NET开发者大会将于苏州举办疫情常态化的情况下为确保大会顺利进行大会组委会从会议内容、会务筹备等方面均进行了全面的精细准备以下是组委会发布的参会防疫指南敬请所有现场参会的小伙伴认真阅读并严格按照防疫需求作相应准备▽为保证大会的顺利召开&am…

tensorflow打印模型图_从Tensorflow模型文件中解析并显示网络结构图(pb模型篇)...

最近看到一个巨牛的人工智能教程&#xff0c;分享一下给大家。教程不仅是零基础&#xff0c;通俗易懂&#xff0c;而且非常风趣幽默&#xff0c;像看小说一样&#xff01;觉得太牛了&#xff0c;所以分享给大家。平时碎片时间可以当小说看&#xff0c;【点这里可以去膜拜一下大…

算法题目——省份数量(dfs,bfs)

题目链接:leetcode.547省份数量 dfs: 深度优先遍历:递归 思路:读入数据完成后 重点:建立一个数组记录该省份是否访问,新建一个元素记录省份圈的个数 1.对所有省份循环一次,如果该省份未被访问,则进入dfs 2.dfs中,对所有省份循环一遍,如果未被访问且省份index可以到达…

两台思科交换机vlan划分_Cisco交换机Vlan划分及ACL配置详细步骤 | 吴文辉博客

一、开机1、如是新设备&#xff0c;开机需跳过系统默认配置模式&#xff0c;进入手动配置模式。2、进入用户模式&#xff0c;系统提示符为 >&#xff0c;此模式只能查看统计信息&#xff0c;无配置功能。3、用户模式下&#xff0c;输入 enable &#xff0c;进入特权模式&…

用重构指导Clean Code(二):依恋情结和switch语句

书接上回&#xff0c;我们继续聊如何用重构指导Clean Code。在Clean Code的3.4节中有这样一段代码&#xff08;代码清单3-4&#xff09;。&#xff08;第3章主要讲的是函数&#xff0c;而3.4节讨论的是switch语句。&#xff09;public Money calculatePay(Employee e) throws I…

算法题目——杨辉三角问题

思路: #include<iostream> #include<cstdio> #include<cstring> #

cascade down_Cascaded CNN 方法寻找人脸关键点

Cascaded CNN 方法寻找人脸关键点论文笔记阅读论文第一阶段阅读论文&#xff0c;大约两天大体阅读完论文 Deep Convolutional Network Cascade for Facial Point Detection。感觉还是比较缺乏论文阅读经验&#xff0c;但是比以前快了很多。主要阅读论文 intro、method 和 model…

了解一下HTTP1.1 Pipelining技术

为什么谈HTTP1.1 Pipelining呢&#xff1f;主要问题根源还是来源于Beetlex参加了techempower的测试。先看一下以下两项测试的结果&#xff1a;以上分别是.net平台的Json和Plaintext的测试结果&#xff0c;其实Plaintext最高能跑700多万RPS已经完全超了对网络IO读写损耗的认知&a…

springboot2 多线程写入数据_解决SpringBoot项目使用多线程处理任务时无法通过@Autowired注入bean问题...

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":7,"count":7}]},"card":[{"des":"EDAS 是一个应用托管和微服务管理的PaaS平台…

算法题目——子序列和问题(poj-3061)(尺取法)

题目链接:POJ-3061 题意:给定一个序列,使得其和大于或等于S,求最短的子序列长度。 问题分析: 1.首先序列都是正整数,当子序列和大于等于S时,已经没有必要再将右端点继续向右移动。因为再向右移动,序列的长度一定会大于此时的长度 2.所以,当子序列和小于S时,右端点向…

读书 | 数字化转型的道与术(下)

【数字化转型】| 作者 / Edison Zhou这是EdisonTalk的第313篇学习总结 最近在阅读钟华老师的新作《数字化转型的道与术》&#xff0c;记录和总结了一些学习笔记和感想&#xff0c;整理成文分享与你&#xff0c;本文为下半部分&#xff0c;希望能对也在参与数字化转型的各位童鞋…

算法题目——读书知识点统计问题(POJ-3320)(尺取法)

题目链接:poj-3320 问题:杰西卡是一个非常可爱的女孩,受到许多男孩的追捧。最近她有个问题。期末考试快到了,但她几乎没花什么时间。如果她想通过考试,她必须掌握一本厚厚的教科书中包含的所有思想。那本教科书的作者和其他作者一样,对这些观点极为挑剔,因此有些观点被…

aop springboot 传入参数_Springboot添加AOP打印请求参数

1. 引入依赖org.springframework.bootspring-boot-starter-aop2. 写切面切面类需要加Aspect和Component注解package com.test.demo.aspect;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.Pro…

GraphQL:面对复杂类型

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余&#xff0c;也让 API 更容易地随着时间推移而演进&#xff0c…

算法与数据结构——并查集

文章推荐:【算法与数据结构】—— 并查集 例子: 数据结构——最小生成树之克鲁斯卡尔算法(Kruskal) 1.2 并查集思想(重点) 我们可以把每个连通分量看成一个集合,该集合包含了连通分量的所有点。而具体的连通方式无关紧要,好比集合中的元素没有先后顺序之分,只有“属于”…

eclipse 输入卡顿_7个小技巧,解决eclipse卡顿问题

eclipse作为开发工具&#xff0c;每天都要使用&#xff0c;你肯定遇到过eclipse卡到想哭的时刻&#xff0c;严重影响开发效率啊&#xff01;如果内存条不要钱&#xff0c;那就加内存吧&#xff01;一个不够加两个&#xff01;当然这都是玩笑话&#xff0c;如果不花钱也能解决问…