zoukankan      html  css  js  c++  java
  • 全局异常处理机制(Filter拦截器对比)

    ASP.NET Core 中间件的使用(三):全局异常处理机制(Filter拦截器对比)

     

    前言

    只是Filter拦截器的对比,还不是中间件,注意甄别

    我们经常听到“秒修复秒上线”,觉得很厉害的样子。

    其实不然,这只是一个调侃而已,出现问题的方式很多(逻辑漏洞、代码异常、操作方式不正确等)。

    我们今天来说代码异常问题怎么快速定位,减少不必要的时间浪费。

    这就是今天的主题“添加全局异常处理机制”捕捉异常存储到数据库(mongodb、SqlServer、MySQL等)。

    PS:输出txt的话不怎么友好,不是所有人都能登录服务器的。

    异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止。

    创建项目

    我们创建一个ASP.NET Core Web API项目,选择.NET Core3.1。

    创建全局异常过滤器

    在控制器里面创建一个异常过滤器,命名为ExceptionFilter.cs,过滤器继承IExceptionFilter接口。

    注意,我这里入库用的是efcore+sqlserver,大家可以根据自己实际情况使用ORM和数据库方式。

    异常过滤器,顾名思义,就是当程序发生异常时所使用的过滤器。用于在系统出现未捕获异常时的处理。

    实现一个自定义异常过滤器,自定义一个全局异常过滤器需要实现IExceptionFilter接口

    IExceptionFilter接口会要求实现OnException方法,当系统发生未捕获异常时就会触发这个方法。

    OnException方法有一个ExceptionContext异常上下文,其中包含了具体的异常信息,HttpContext及mvc路由信息。

    系统一旦出现未捕获异常后,比较常见的做法就是使用日志工具,将异常的详细信息记录下来,方便修正调试。

    下面是日志记录的实现。

    复制代码
    using Microsoft.AspNetCore.Mvc.Filters;
    using System;
    
    namespace Log4NetWebAPI.Controllers
    {
        public class ExceptionFilter: IExceptionFilter
        {
            //全局异常处理机制
            public void OnException(ExceptionContext context)
            {
                Exception ex = context.Exception;
    
                //错误所在的控制器方法名称
                var DisplayName = context.ActionDescriptor.DisplayName;
    
                #region 错误所在的行号行号
    
                ////行号前的名称有的是中文,有的是英文,注意甄别
                //var aaa = ex.StackTrace.Substring(ex.StackTrace.IndexOf("行号"), ex.StackTrace.Length - ex.StackTrace.IndexOf("行号"));
                //var ccc = ex.StackTrace.Substring(ex.StackTrace.IndexOf("line"), ex.StackTrace.Length - ex.StackTrace.IndexOf("line"));
                var lineNumber = 0;
                const string lineSearch = ":line ";
                var index = ex.StackTrace.LastIndexOf(lineSearch);
                if (index != -1)
                {
                    var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
                    var lineNumberStr = lineNumberText.Substring(0, lineNumberText.IndexOf("\r\n"));
                    if (int.TryParse(lineNumberStr, out lineNumber))
                    {
    
                    }
                }
    
                #endregion
    
                #region 写入信息到【数据库】,这里自行入库即可(mongodb、SqlServer、MySQL等),我以SqlServer为例
    
                errorLog md = new errorLog();
                md.logTime = DateTime.Now;
                md.logType = "error";
                md.displayName = DisplayName;  //错误位置
                md.lineNumber = lineNumber;  //错误行号
                md.message = ex.Message;    //错误信息
                md.messagedetails = ex.ToString();  //错误详情
                md.createTime= DateTime.Now;
    
                using (var ctx = new dbContext())
                {
    
                    ctx.Add(md);
                    ctx.SaveChanges();
                }
                #endregion
    
                //下面是你的返回页面显示的内容提示,以下省略
    
            }
        }
    }
    复制代码

    依赖注入全局异常处理机制

    Startup.cs里面把我们刚刚创建的全局异常处理机制注入,放到ConfigureServices方法里面。

    //添加全局异常处理机制
    services.AddMvc(option => {
      option.Filters.Add<ExceptionFilter>();
    });

    复制代码
     // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
    
                //添加全局异常处理机制
                services.AddMvc(option => {
                    option.Filters.Add<ExceptionFilter>();
                });
            }
                
    复制代码

    测试全局异常处理机制

    “将string字符串转换为int类型,如下代码,肯定是报错的,我们来捕捉一下错误信息入库。

    var numberNo = "我是序列号";
    //这里是转换为int类型,然后数据源是string,肯定报错,然后我们全局捕捉
    //注意,我们这里没有写try catch
    var number = Convert.ToInt32(numberNo);

    运行项目后我们查询一下数据库,发现捕捉到错误信息了,包括

    错误时间:2021-09-28 15:12:58.307

    日志类型:error

    错误的方法位置:Log4NetWebAPI.Controllers.WeatherForecastController.Get (Log4NetWebAPI),

    错误的行号:36行,

    错误的信息:Input string was not in a correct format.(输入字符串的格式不正确。)

    下面是控制器方法截图


    推荐资料

    参考文献

  • 相关阅读:
    c#读取INI文件
    无题
    tnsping 命令解析
    宁静——一种心灵的奢望
    .NET框架类别
    19任意三个数的和为15
    VS.NET2005安装过程中遇到error:1935错误时的解决方法
    SQL Server 2005 : 存储过程传递字符串类型参数时,如何在参数中包含单引号
    SQL Server 2005 : 分割字符串
    网站发布在中文操作系统,但ReportViewer的工具栏显示为英文的解决方法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/15708413.html
Copyright © 2011-2022 走看看