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

 更新时间:2021年9月22日 09:59  点击:1756

前言

异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 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全局异常拦截内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • 配置vue全局方法的两种方式实例

    vue项目中有一些方法需要在多个页面调用,但为了避免在每个页面都import进来,可以把方法加到原型上去,这样在每个组件中都能使用了,下面这篇文章主要给大家介绍了关于配置vue全局方法的两种方式,需要的朋友可以参考下...2021-09-13
  • Angular处理未可知异常错误的方法详解

    这篇文章主要给大家介绍了关于Angular如何处理未可知异常错误的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-17
  • Python同时处理多个异常的方法

    这篇文章主要介绍了Python同时处理多个异常的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-29
  • vue+axios全局添加请求头和参数操作

    这篇文章主要介绍了vue+axios全局添加请求头和参数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-24
  • vue设置全局访问接口API地址操作

    这篇文章主要介绍了vue设置全局访问接口API地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-14
  • java中的空指针异常情况以及解决方案

    这篇文章主要介绍了java中的空指针异常情况以及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-02
  • 详解C#编程中异常的创建和引发以及异常处理

    这篇文章主要介绍了C#编程中异常的创建和引发以及异常处理,文中介绍了Catch块和Finally块等基本的异常处理要点,需要的朋友可以参考下...2020-06-25
  • JS中正则表达式全局匹配模式 /g用法详解

    本文章通过实例代码给大家详细介绍js中正则表达式的全局匹配模式 g的用法,需要的朋友参考下...2017-04-03
  • Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.Transformer异常

    这篇文章主要介绍了Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type异常,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-10
  • Spring异常捕获且回滚事务解决方案

    这篇文章主要介绍了Spring异常捕获且回滚事务解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-03
  • 通过实例了解Python异常处理机制底层实现

    这篇文章主要介绍了通过实例了解Python异常处理机制底层实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-24
  • PHP捕捉异常中断的方法

    相信每位PHP程序员都知道,当PHP程序出现异常情况,如出现致命错误、超时或者不可知的逻辑错误导致程序中断,这个时候就可以用 register_shutdown_function进行异常处理。下面本文给出了详细的示例代码,有需要的朋友们下面来一起看看吧。...2016-10-25
  • Postman环境变量全局变量使用方法详解

    这篇文章主要介绍了Postman环境变量全局变量使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-13
  • C#异常处理知识汇总

    这篇文章主要介绍了C#异常处理的知识,文中讲解非常详细,配合代码帮助大家更好的理解,感兴趣的朋友可以参考下...2020-06-25
  • Oracle用户自定义异常实现过程解析

    这篇文章主要介绍了Oracle用户自定义异常实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-29
  • java抛出异常的几种情况小结

    这篇文章主要介绍了java抛出异常的几种情况小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-02
  • subsonic3.0插件更新字符串过长引发的异常修复方法

    这篇文章主要介绍了subsonic3.0插件更新字符串过长引发的异常修复方法,需要的朋友可以参考下...2021-09-22
  • DWR异常情况处理常见方法解析

    这篇文章主要介绍了DWR异常情况处理常见方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-16
  • 你应该知道的.NET错误与异常处理机制

    这篇文章主要给大家介绍了关于.NET错误与异常处理机制的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用.NET具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2021-09-22
  • python全局变量引用与修改过程解析

    这篇文章主要介绍了python全局变量引用与修改过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-04-30