利用MVC异常过滤器捕获异常并写入日志记录

有人与我立黄昏,有人问我粥可温。有人与我捻熄灯,有人共我书半生。——2019/1/22

延续上一篇MVC过滤器使用实例

异常过滤器,顾名思义,就是当程序发生异常时所使用的过滤器。用于在系统出现未捕获异常时的处理。
异常过滤器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行。异常过滤器可用于执行诸如日志记录或显示错误页之类的任务。自定义异常筛选器继承自HandleErrorAttribute

代码很简单:在App_Start里新建一个自定义异常处理类,继承HandleErrorAttribute,并重写OnException。
另外需要新建一个文件夹,用来存储日志文件。下面代码会体现到

 public class ErrorAttribute: HandleErrorAttribute
    {
        /// <summary>
        /// 在发生异常时触发调用
        /// </summary>
        public override void OnException(ExceptionContext filterContext)
        {
            //if (!filterContext.ExceptionHandled && filterContext.Exception is NullReferenceException)
            if (!filterContext.ExceptionHandled)
            {
                //获取出现异常的controller名和action名,用于记录
                string controllerName = (string)filterContext.RouteData.Values["controller"];
                string actionName = (string)filterContext.RouteData.Values["action"];
                //定义一个HandErrorInfo,用于Error视图展示异常信息
                HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                string thisTime = DateTime.Now.ToShortDateString().Replace("/","");
                string errorDetails = $"出错时间:{DateTime.Now.ToString()},错误发生在{model.ControllerName}控制器的{model.ActionName},错误类型:{model.Exception.Message}";
                string splitLine = "——————————————————————分割线——————————————————————";
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"E:\ybbb\YbbFighting\YbbFighting\ErrorTxt\"+ thisTime, true))
                {
                    file.WriteLine(errorDetails);
                    file.WriteLine(model.Exception.StackTrace);
                    file.WriteLine(splitLine);  
                    
                }
                
                ViewResult result = new ViewResult
                {
                    ViewName = this.View,//设置异常时跳转的404页面
                    ViewData = new ViewDataDictionary<HandleErrorInfo>(model)  //定义ViewData,泛型
                };
                filterContext.Result = result;
                filterContext.ExceptionHandled = true;//设置异常已处理
            }
            
        }
    }

注意下System.IO.StreamWriter,如果文件存在,设置为ture则向文件追加内容
利用MVC异常过滤器捕获异常并写入日志记录
在App_Start的FilterConfig里注册我们刚才写的自定义异常筛选器
利用MVC异常过滤器捕获异常并写入日志记录
新建一个Error页,就是我们注册时初始化的View,这里我发现即使不初始化View为Error,最后也会自己定向到Error页面,但是我把Error改名为Error1时,就会报错找不到Error页面,百度了下也没看到类似的情况,我也根本没在配置文件里配置这个。猜想可能是异常筛选器底层默认是Error吧。如果有大佬知道,麻烦告诉下。谢谢!
利用MVC异常过滤器捕获异常并写入日志记录

        public ActionResult NewErrorDemo()
        {
            throw new Exception("我抛出了一个错误!");
            return View();
        }

运行程序:
利用MVC异常过滤器捕获异常并写入日志记录

日志信息如图:
利用MVC异常过滤器捕获异常并写入日志记录