> 文档中心 > asp net mvc 全局捕获异常的方法

asp net mvc 全局捕获异常的方法

在一个网站的开发测试阶段,我们经常需要全局捕获异常。使得网站在异常发生时并不会整个崩掉,从而影响到所有用户的访问,同时记录下异常的详细信息,以便于网站维护人员在异常发生后,可以准确定位异常所在位置和原因。本文使用过滤器的方式来实现全局异常捕获。网上也有很多类似的博文教程,我这里整理了一份日志打印比较完整的。

新建过滤器

在您的Util项目添加过滤器ExceptionLogAttribute.cs:

using System;using System.Web;using System.Web.Mvc;using YourNameSpace.Util.Helpper;using NLog;namespace YourNameSpace.Util.Extensions{    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]    public class ExceptionLogAttribute : HandleErrorAttribute    { public override void OnException(ExceptionContext filterContext) {     if (!filterContext.ExceptionHandled)     {  Logger logger = LogManager.GetCurrentClassLogger();  try  {      var controllerName = (string)filterContext.RouteData.Values["controller"];      var actionName = (string)filterContext.RouteData.Values["action"];      var memberId = filterContext.Controller.ViewBag.MemberId;      var exception = filterContext.Exception;      if (filterContext.HttpContext != null && filterContext.HttpContext.Request != null)      {   if (filterContext.HttpContext.Request.RequestType == "GET")   {var requestUrl = filterContext.HttpContext.Request.Url.ToString();var requestParas = filterContext.HttpContext.Request.Params;if (requestParas != null){    var reqParaStr = HttpUtility.UrlDecode(requestParas.ToString());    logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId, requestUrl, reqParaStr));}else{    logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId, requestUrl));}   }   else if (filterContext.HttpContext.Request.RequestType == "POST")   {var requestUrl = filterContext.HttpContext.Request.Url.ToString();var requestParas = filterContext.HttpContext.Request.Params;if (requestParas != null){    var reqParaStr = HttpUtility.UrlDecode(requestParas.ToString());    logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId, requestUrl, reqParaStr));}else{    logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId, requestUrl));}   }   else   {logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId));   }      }      else      {   logger.Error(LoggerHelper.GetErrorMsg(exception, controllerName, actionName, memberId));      }  }  catch (Exception e)  {      logger.Error(LoggerHelper.GetErrorMsg(e, "ExceptionLogAttribute", "异常过滤器", "未知"));  }     }     filterContext.ExceptionHandled = true; }    }}

关于NLog的配置和使用,本文不再赘述。可自行百度进行配置。

在您的Util项目中添加日志帮助类LoggerHelper.cs:

using System;using System.Text;namespace YourNameSpace.Util.Helpper{    public class LoggerHelper    { public static string GetErrorMsg(Exception exception, string controllerName, string actionName, Guid memberId, string requestUrl = null, string requestParams = null, string extraMsg = null) {     return GetErrorMsg(exception, controllerName, actionName, memberId.ToString(), requestUrl, requestParams, extraMsg); } ///  /// 获取接口异常详细信息函数 ///  /// 异常对象 /// 控制器名称 /// 接口名称 /// 用户Id /// 请求URL /// 请求参数 /// 需要额外打印输出的日志信息 ///  public static string GetErrorMsg(Exception exception, string controllerName, string actionName, string memberId, string requestUrl = null, string requestParams = null, string extraMsg = null) {     var erroMsg = new StringBuilder();     if (!string.IsNullOrWhiteSpace(extraMsg))     {  erroMsg.Append(extraMsg);     }     erroMsg.Append($"控制器:{controllerName}/{actionName} \n") ;     if(string.IsNullOrWhiteSpace(memberId))     {  erroMsg.Append($"无用户Id \n ");     }     else     {  erroMsg.Append($"用户Id:{memberId} \n ");     }     erroMsg.Append($"ExceptionMessage:{exception.Message} \n InnerException:{exception.InnerException} \n StackTrace:{exception.StackTrace} \n");     if (!string.IsNullOrWhiteSpace(requestUrl))     {  erroMsg.Append($"Request.Url:{requestUrl} \n");     }     if (!string.IsNullOrWhiteSpace(requestParams))     {  erroMsg.Append($"Request.Params:{requestParams} \n");     }     return erroMsg.ToString(); }    }}

注册全局过滤器

在【您的web项目】->【App_Start】->【FilterConfig.cs】中引用过滤器,并注册全局异常捕获过滤器。

 

using System.Web.Mvc;using YourNameSpace.Util.Filters;using YourNameSpace.Util.Extensions;namespace YourNameSpace.Web{    public class FilterConfig    { public static void RegisterGlobalFilters(GlobalFilterCollection filters) {     //注册全局过滤器     filters.Add(new HandleErrorAttribute());     //注册全局异常捕获过滤器     filters.Add(new ExceptionLogAttribute()); }    }}

 

全局异常日志打印结果

 

588库千库资源网