ASP.NET MVC HandleError异常过滤器过滤器用法

640?wx_fmt=jpeg

异常过滤器是处理代码异常的,在系统的代码抛错的时候执行,MVC默认已经实现了异常过滤器,并且注册到了App_Start目录下的FilterConfig.cs:

filters.Add(new HandleErrorAttribute());

异常过滤器生效于整个系统,任何接口或者页面报错都会执行MVC默认的异常处理,并返回一个默认的报错页面:Views/Shared/Error(程序发到服务器上报错时才可以看到本页面,本地调试权限高,还是可以看到具体报错信息的)

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <meta name="viewport" content="width=device-width" />

    <title>错误</title>

</head>

<body>

    <hgroup>

        <h1>错误。</h1>

        <h2>处理你的请求时出错。</h2>

    </hgroup>

</body>

</html>

默认的异常过滤器显然无法满足使用需求,重写下异常过滤器,满足项目实际开发中的需求:

1)报错可以记录错误代码所在的控制器和方法,以及报错时的请求参数和时间;

2)返回特定格式的JSON方便前端处理。因为现在系统大部分是ajax请求,报错了返回MVC默认的报错页面,前端不好处理

新建一个类LogExceptionAttribute继承HandleErrorAttribute,并重写内部的OnException方法:

public override void OnException(ExceptionContext filterContext)

 {

     if (!filterContext.ExceptionHandled)

     {

         string controllerName = (string)filterContext.RouteData.Values["controller"];

         string actionName = (string)filterContext.RouteData.Values["action"];

         string param = Common.GetPostParas();

         string ip = HttpContext.Current.Request.UserHostAddress;

         LogManager.GetLogger("LogExceptionAttribute").Error("Location:{0}/{1} Param:{2}UserIP:{3} Exception:{4}", controllerName, actionName, param, ip, filterContext.Exception.Message);


         filterContext.Result = new JsonResult

         {

             Data = new ReturnModel_Common { success = false, code = ReturnCode_Interface.服务端抛错, msg = filterContext.Exception.Message },

             JsonRequestBehavior = JsonRequestBehavior.AllowGet

         };

     }

     if (filterContext.Result is JsonResult)

         filterContext.ExceptionHandled = true;//返回结果是JsonResult,则设置异常已处理

     else

         base.OnException(filterContext);//执行基类HandleErrorAttribute的逻辑,转向错误页面

 }

异常过滤器就不像授权过滤器一样标注在方法上面了,直接到App_Start目录下的FilterConfig.cs注册下,这样所有的接口都可以生效了:

filters.Add(new LogExceptionAttribute());

异常过滤器里使用了NLog作为日志记录工具,Nuget安装命令:

Install-Package NLog 

Install-Package NLog.Config


相比Log4net,NLog配置简单,仅几行代码即可,NLog.config:

<?xml version="1.0" encoding="utf-8" ?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <targets>

    <target xsi:type="File" name="f" fileName="${basedir}/log/${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" />

    <target xsi:type="File" name="f2" fileName="D:logMVCExtension${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" />

  </targets>

  <rules>

    <logger name="*" minlevel="Debug" writeTo="f2" />

  </rules>

</nlog>

如果报错,日志就记录在D盘的log目录下的MVCExtension目录下,一个项目一个日志目录,方便管理。全部配置完成,看下代码:

public JsonResult HandleErrorFilterTest()

 { 

   int i = int.Parse("abc");   

   return Json(new ReturnModel_Data { data = i }); 

}

字符串强转成int类型,必然报错,页面响应:

640?wx_fmt=png

同时日志也记录下来了:

640?wx_fmt=png




原文地址:https://www.cnblogs.com/hgmyz/p/12351569.html