MVC.Net:通过Global.asax捕捉错误

在MVC.Net中,如果我们想做一个统一的错误处理的模块,有几个选择,一种是通过一个Base Controller来实现,另外一种就是在Global.asax中实现。这里介绍后一种方法。

首先打开Global.asax文件,然后添加如下代码:

  1 /**
  2  * 捕捉系统级错误
  3  **/
  4 void Application_Error(object sender, EventArgs e)
  5 {
  6     // We clear the response
  7     Response.Clear();
  8 
  9     // 获取错误类
 10     Exception exc = Server.GetLastError();
 11 
 12     // 检查是否Ajax请求,如果是的话,需要返回JSon结果
 13     if (IsAjaxRequest())
 14     {
 15         Response.Write("JSon结果");
 16     }
 17     else
 18     {
 19         // 单独显示404页面
 20         if (is404Error(exc)) {
 21             Response.Redirect("/ERROR/E404");
 22         }
 23         else
 24         {
 25 #if DEBUG
 26             // 仅在调试阶段显示错误信息页面
 27             StringBuilder sb = new StringBuilder();
 28             sb.Append("<html>");
 29             sb.AppendFormat(@"<body onload='document.forms[""form""].submit()'>");
 30             sb.AppendFormat("<form name='form' action='{0}' method='post'>", "/ERROR/DevOnly");
 31             sb.AppendFormat("<input type='hidden' name='message' value='{0}'>", 
 32                 HttpUtility.UrlEncode(exc.Message));    // 此处必须Encode,否则单引号无法正确显示
 33             sb.AppendFormat("<input type='hidden' name='source' value='{0}'>",
 34                 HttpUtility.UrlEncode(exc.Source));    // 此处必须Encode,否则单引号无法正确显示
 35             sb.AppendFormat("<input type='hidden' name='stackTrace' value='{0}'>",
 36                 HttpUtility.UrlEncode(exc.StackTrace));    // 此处必须Encode,否则单引号无法正确显示
 37             sb.AppendFormat("<input type='hidden' name='innerException' value='{0}'>",
 38                 HttpUtility.UrlEncode(exc.InnerException != null ? exc.InnerException.Message : ""));    // 此处必须Encode,否则单引号无法正确显示
 39             
 40             sb.Append("</form>");
 41             sb.Append("</body>");
 42             sb.Append("</html>");
 43 
 44             Response.Write(sb.ToString());
 45 
 46             Response.End();
 47 #else
 48             Response.Redirect("/ERROR/");
 49 #endif
 50         }
 51     }
 52 
 53     //We clear the error
 54     Server.ClearError();
 55 }
 56 
 57 /// <summary>
 58 /// 检查是否属于404错误
 59 /// </summary>
 60 /// <param name="exc"></param>
 61 /// <returns></returns>
 62 private bool is404Error(Exception exc)
 63 {
 64     // Handle HTTP errors
 65     if (exc.GetType() == typeof(HttpException))
 66     {
 67         var httpException = (HttpException)exc;
 68         if (httpException.GetHttpCode() == 404)
 69             return true;
 70     }
 71 
 72     return false;
 73 }
 74 
 75 
 76 /// <summary>
 77 /// 检查是否是Ajax请求
 78 /// </summary>
 79 /// <returns></returns>
 80 private bool IsAjaxRequest()
 81 {
 82     //The easy way
 83     bool isAjaxRequest = (Request["X-Requested-With"] == "XMLHttpRequest")
 84     || ((Request.Headers != null)
 85     && (Request.Headers["X-Requested-With"] == "XMLHttpRequest"));
 86 
 87     //If we are not sure that we have an AJAX request or that we have to return JSON 
 88     //we fall back to Reflection
 89     if (!isAjaxRequest)
 90     {
 91         try
 92         {
 93             //The controller and action
 94             string controllerName = Request.RequestContext.
 95                                     RouteData.Values["controller"].ToString();
 96             string actionName = Request.RequestContext.
 97                                 RouteData.Values["action"].ToString();
 98 
 99             //We create a controller instance
100             DefaultControllerFactory controllerFactory = new DefaultControllerFactory();
101             Controller controller = controllerFactory.CreateController(
102             Request.RequestContext, controllerName) as Controller;
103 
104             //We get the controller actions
105             ReflectedControllerDescriptor controllerDescriptor =
106             new ReflectedControllerDescriptor(controller.GetType());
107             ActionDescriptor[] controllerActions =
108             controllerDescriptor.GetCanonicalActions();
109 
110             //We search for our action
111             foreach (ReflectedActionDescriptor actionDescriptor in controllerActions)
112             {
113                 if (actionDescriptor.ActionName.ToUpper().Equals(actionName.ToUpper()))
114                 {
115                     //If the action returns JsonResult then we have an AJAX request
116                     if (actionDescriptor.MethodInfo.ReturnType
117                     .Equals(typeof(JsonResult)))
118                         return true;
119                 }
120             }
121         }
122         catch
123         {
124 
125         }
126     }
127 
128     return isAjaxRequest;
129 }

在显示错误页面的地方,使用了将Reponse Redirect从Get变为Post的技巧,可以参考以前的文章

原文地址:https://www.cnblogs.com/ilovewindy/p/3795826.html