异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 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();                    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();            if (iExceptionHandlerFeature != null)            {                string path = iExceptionHandlerFeature.Path;                Exception exception = iExceptionHandlerFeature.Error;                //Write code here to log the exception details                return View("Error",iExceptionHandlerFeature);            }                            return View();        }        [HttpGet("/Error/NotFound/{statusCode}")]        public IActionResult NotFound(int statusCode)        {            var iStatusCodeReExecuteFeature =HttpContext.Features.Get();            return View("NotFound",iStatusCodeReExecuteFeature.OriginalPath);        }    }

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

string route = iExceptionHandlerFeature.Path;

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

var exception = HttpContext.Features.Get();

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

使用 View 展示错误信息

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

@model Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature@{    ViewData["Title"] = "Index";    Layout = "~/Views/Shared/_Layout.cshtml";}

Error: @Model.Error.Message

@Model.Error.StackTrace

@Model.Error.InnerException

下面是 NotFound 页面的 代码

@model string@{    ViewData["Title"] = "NotFound";    Layout = "~/Views/Shared/_Layout.cshtml";}    

Error: The requested URL @Model was not found!

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

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

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

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

更多高质量干货:参见我的 GitHub: dotnetfly**

获取异常信息_如何在 ASP.NET Core 中实现全局异常拦截相关推荐

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

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

  2. asp绑定gridview属性_如何在ASP.NET Core中自定义Azure Storage File Provider

    主题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者: Lamond Lu 地址:  https://www.cnblogs.com/lwqlun/ ...

  3. asp英语是什么意思_如何在ASP.NET Core中使用JSON Patch

    原文: JSON Patch With ASP.NET Core 作者:.NET Core Tutorials 译文:如何在ASP.NET Core中使用JSON Patch 地址:https://w ...

  4. 如何在 ASP.Net Core 中使用 Configuration Provider

    ASP.NET Core 是一个开源的,跨平台的,精简的模块化框架,可用于构建高性能,可扩展的web应用程序, ASP.NET Core 中的数据配置常用 k-v 的形式存储,值得注意的是,新的数据配 ...

  5. 如何在ASP.NET Core中使用Azure Service Bus Queue

    原文:USING AZURE SERVICE BUS QUEUES WITH ASP.NET CORE SERVICES 作者:damienbod[1] 译文:如何在ASP.NET Core中使用Az ...

  6. 如何在ASP.NET Core中自定义Azure Storage File Provider

    主题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者: Lamond Lu 地址:  https://www.cnblogs.com/lwqlun/ ...

  7. 如何在 ASP.Net Core 中使用 Lamar

    ASP.Net Core 自带了一个极简的 开箱即用 的依赖注入容器,实际上,你还可以使用第三方的 依赖注入容器 来替代它,依赖注入是一种设计模式,它能够有效的实现对象之间的解耦并有利于提高单元测试和 ...

  8. 如何在 ASP.Net Core 中使用 NCache

    虽然 ASP.Net Core 中缺少 Cache 对象,但它引入了三种不同的cache方式. 内存缓存 分布式缓存 Response缓存 Alachisoft 公司提供了一个开源项目 NCache, ...

  9. 如何在 ASP.Net Core 中使用 Serilog

    记录日志的一个作用就是方便对应用程序进行跟踪和排错调查,在实际应用上都是引入 日志框架,但如果你的 日志文件 包含非结构化的数据,那么查询起来将是一个噩梦,所以需要在记录日志的时候采用结构化方式. 将 ...

最新文章

  1. 2014---努力才是真天赋
  2. 自学转行学AI人工智能怎么样?
  3. 截取字符串,但要保证汉字不被截取半个
  4. install ADT plugin
  5. 电场 大学_人工电场优化算法
  6. Web 版 VS Code (Visual Studio Online) 即将来临!
  7. Linux学习笔记-消息队列概念
  8. Java是如何实现自己的SPI机制的?
  9. CorePress-v4.5网站主题 WordPress主题
  10. 华为全球第一、荣耀中国前二!余承东宣布新目标:苹果三星怎么看?
  11. Spring集合类型属性注入
  12. 数据库开发基础-教案-3-认识数据库备份和事务日志备份
  13. 一文看尽Facebook 3D视觉技术研究进展
  14. mac jenkins下载与安装
  15. kindle 耗电飞速,电池坏了?你可能给kindle“吃了有毒的食物”
  16. 东京通勤概况及奥运会交通措施
  17. 计算机重装后不能启动怎么办,重装系统后无法进入系统怎么办 修复进不去系统方法教程...
  18. 不小心格式化了硬盘怎么恢复数据?
  19. 密码箱忘记密码解决方法
  20. Unity 基础 之 在 UGUI 上简单实现VideoPlayer视频播放的功能,简单暂停播放/显示视频名称/显示时长/拖拽播放等

热门文章

  1. 《Java和Android开发学习指南(第2版)》——第2章,第2.10节本章小结
  2. C#获取刚插入的数据的id
  3. information_schema.character_sets 学习
  4. 精妙SQL语句收集(转)
  5. ReactiveCocoa源码拆分解析(四)
  6. 转: RSA原理 阮一峰的博客
  7. Openssl的证书格式转换
  8. C语言程序设计 文件操作函数
  9. leetcode116. 填充每个节点的下一个右侧节点指针(dfs)
  10. java python算法_用Java,Python和C ++示例解释的搜索算法