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 details
  return 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 异常时当时的请求路径,对了,要想用上 IExceptionHandlerPathFeature 和 IStatusCodeReExecuteFeature ,要记得在 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/art...

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

到此这篇关于ASP.NET Core中实现全局异常拦截的文章就介绍到这了,更多相关ASP.NET Core全局异常拦截内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ASP.NET CORE学习教程之自定义异常处理详解

    为什么异常处理选择中间件? 传统的ASP.NET可以采用异常过滤器的方式处理异常,在ASP.NET CORE中,是以多个中间件连接而成的管道形式处理请求的,不过常用的五大过滤器得以保留,同样可以采用异常过滤器处理异常,但是异常过滤器不能处理MVC中间件以外的异常,为了全局统一考虑,采用中间件处理异常更为合适 为什么选择自定义异常中间件? 先来看看ASP.NET CORE 内置的三个异常处理中间件 DeveloperExceptionPageMiddleware, ExceptionHandler

  • ASP.NET Core异常和错误处理(8)

    在这一章,我们将讨论异常和错误处理.当 ASP.NET Core应用程序中发生错误时,您可以以各种不同的方式来处理.让我们来看看通过添加一个中间件来处理异常情况,这个中间件将帮助我们处理错误. 要模拟出错,让我们转到应用程序,运行,如果我们只是抛出异常的话,看看程序是如何运转转的. using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft

  • ASP.NET Core中实现全局异常拦截的完整步骤

    前言 异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 ASP.Net Core MVC 中实现全局异常处理,我会用一些 样例代码 和 截图 来说明这些概念. 全局异常处理 其实在 ASP.Net Core MVC 框架中已经有了全局异常处理的机制,你可以在一个中心化的地方使用 全局异常处理中间件 来进行异常拦截,如果不用这种中心化方式的话,你就只能在 Controller 或者 Action 作用域上单独处理,这会导致异常处理代码零散在项目各

  • ASP.NET Core中预压缩静态文件的方法步骤

    前言 Web应用程序的优化是非常重要,因为使用更少的CPU,占用更少的带宽可以减少项目的费用. 在ASP.NET Core中我们可以很容易的启用响应压缩,但是针对预压缩文件,就需要做一些额外的功能了. 这篇博客文章展示了如何在ASP.NET Core中预压缩静态文件. 下面话不多说了,来一起看看详细的介绍吧 为什么需要预压缩文件? 虽然在从服务器请求文件时, 我们可以动态压缩文件,但这意味这Web服务器需要做更多的额外工作. 其实只有在新的应用程序部署时才会更改要压缩的文件. 越好的压缩效果需要

  • ASP.NET Core中快速构建PDF文档的步骤分享第1/2页

    比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发,随着这并不难,但还是会手忙脚乱的去搜索一些资料,那么恭喜您,这篇帖子会帮助到您,我们就不会再去浪费一些宝贵的时间. 在本文中我们将要使用DinkToPDF来处理我们在.NET Core Web 程序中进行构建PDF文档!就现在我们不多说,直接开始有趣的部分. 前言# 您可以通过创建PDF文档在我的仓库中,获取源代码,欢迎给个免费的Star... 现在我们创建一个.NET Core 3.0 项目,至于是mvc.Api.

  • Asp.Net Core对接钉钉群机器人的完整步骤记录

    前言 钉钉作为企业办公越来越常用的软件,对于企业内部自研系统提供接口支持,以此来打通多平台下的数据,本次先使用最简单的钉钉群机器人完成多种形式的消息推送,参考钉钉开发文档中自定义机器人环节,此次尝试所花的时间不多,但有几个地方是需要注意的. 一.钉钉群中建立机器人获取WebHook地址 首先得有一个钉钉群,如果没有得自行创建一个了,通过群内右上角菜单中找到群机器人然后添加一个自定义机器人 并设置消息推送开启(默认是开启),复制下一行的webhook地址,该地址将作为后面消息推送的地址 完成即可,

  • 在 ASP.NET Core 中为 gRPC 服务添加全局异常处理

    目录 一.咨询区 Dmitriy 二.回答区 valentasm 三.点评区 以下文章来源于公众号:DotNetCore实战 一.咨询区 Dmitriy 在 ASP.NET Core 中使用GRPC.ASPNETCore 工具包写 gRPC 服务,想实现 gRPC 的异常全局拦截, 代码如下: app.UseExceptionHandler(configure => {     configure.Run(async e =>     {         Console.WriteLine(&

  • 在spring中手写全局异常拦截器

    为什么要重复造轮子 你可能会问,Spring已经自带了全局异常拦截,为什么还要重复造轮子呢? 这是个好问题,我觉得有以下几个原因 装逼 Spring的全局异常拦截只是针对于Spring MVC的接口,对于你的RPC接口就无能为力了 无法定制化 除了写业务代码,我们其实还能干点别的事 我觉得上述理由已经比较充分的解答了为什么要重复造轮子,接下来就来看一下怎么造轮子 造个什么样的轮子? 我觉得全局异常拦截应该有如下特性 使用方便,最好和spring原生的使用方式一致,降低学习成本 能够支持所有接口

  • ASP.NET Core中调整HTTP请求大小的几种方法详解

    一.前言 之所以称ASP.NET Core是一个Web开发平台,源于它具有一个极具扩展性的请求处理管道,我们可以通过这个管道的定制来满足各种场景下的HTTP处理需求.ASP. NET Core应用的很多特性,比如路由.认证.会话.缓存等,也同时定制消息处理管道来实现的.我们甚至可以通过管道定制在ASP.NET Core平台上创建我们自己的Web框架,实际上MVC和SingalR这两个重要的Web框架也是采用这样的方式创建的. HTTP协议自身的特性决定了任何一个Web应用的工作方式都是监听.接收

  • ASP.NET Core中MVC模式实现路由一

    目录 1.前言 2.设置路由中间件 3.传统路由 4.多个路由 4.1定义多个路由 4.2区分操作 5.属性路由 5.1 属性路由 5.2 使用 Http[Verb] 属性的属性路由 5.3合并路由 5.4指定属性路由的可选参数.默认值和约束 5.4自定义属性路由 相关文章 ASP.NET Core中MVC模式实现路由一 ASP.NET Core中MVC模式实现路由二 1.前言 ASP.NET Core MVC使用路由中间件来匹配传入请求的URL并将它们映射到操作(Action方法).路由在启动

  • ASP.NET Core MVC 配置全局路由前缀

    ASP.NET Core MVC 配置全局路由前缀 前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Api 应用程序的时候,有没有遇到过这种场景,就是所有的接口都是以 /api 开头的,也就是我们的api 接口请求地址是像这样的: http://www.example.com/api/order/333 或者是这样的需求 http://www.exa

  • 谈谈如何在ASP.NET Core中实现CORS跨域

    CORS(Cross-origin resource sharing)是一个W3C标准,翻译过来就是 "跨域资源共享",它主要是解决Ajax跨域限制的问题. CORS需要浏览器和服务器支持,现在所有现代浏览器都支持这一特性.注:IE10及以上 只要浏览器支持,其实CORS所有的配置都是在服务端进行的,而前端的操作浏览器会自动完成. 在本例中,将演示如何再ASP.NET Core中实现CORS跨域. 前期准备 你需要windows系统. 你需要安装IIS. 推荐使用VS2015 Upda

随机推荐