在MVC的Global.asax Application_Error 中处理全局错误。
如果在未到创建请求对象时报错,此时 Context.Handler == null 。
判断为Ajax请求时,我们返回Json对象字符串。不是Ajax请求时,转到错误显示页面。
/// <summary> /// 全局错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Application_Error(object sender, EventArgs e) { Exception ex = Server.GetLastError(); LogHelper.Error(ex); // 记录错误日志(NLog 挺好用的(* ̄︶ ̄)) if (Context.Handler == null) { return; } if (new HttpRequestWrapper(Request).IsAjaxRequest()) { Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.Write("{"state":"0","msg":"" + ex.Message + ""}"); Response.Flush(); Response.End(); } else { // 方案一 重定向到错误页面,带上简单的错误信息 //string errurl = "/Error/Error?msg=" + ex.Message; //Response.Redirect(errurl, true); // 方案二 带上错误对象,转到错误页 Response.Clear();
RouteData routeData = new RouteData();
routeData.Values.Add("Controller", "Shared"); // 已有的错误控制器
routeData.Values.Add("Action", "Error"); // 自定义的错误页面
Server.ClearError();
SharedController controller = new SharedController(); // 自定义错误页面控制器
string errController = Request.RequestContext.RouteData.Values["Controller"].ToString();
string errAction = Request.RequestContext.RouteData.Values["Action"].ToString();
HandleErrorInfo handleErrorInfo = new HandleErrorInfo(ex, errController, errAction);
controller.ViewData.Model = handleErrorInfo; //传错误信息
RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData); // 封装与已定义路由匹配的HTTP请求的信息
((IController)controller).Execute(requestContext); //执行上下文请求
Response.End(); } }
其中方案二的对象用法,与默认的错误页(即 /Shared/Error.cshtml)一样。当我们不对错误进行任何处理时,在web.config中可配置错误页到 /Shared/Error.cshtml。
Error.cshtml的代码:
@model System.Web.Mvc.HandleErrorInfo @{ ViewBag.Title = "系统错误"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h3 class="text-danger">系统错误</h3> @if (Model != null) { <span class="text-warning">@(Model.Exception.Message)</span> } else { <span class="text-warning">处理请求时出错。</span> }
方案二的Action的代码:
public ActionResult Error() { return View(); }
相关配置影响:
<!--开启会导致异常不走Application_Error,直接寻Error--> <!--<customErrors mode="On" defaultRedirect="~/Error.cshtml" />-->