大多数人用MVC做项目处理异常时,只监听了IExceptionFilter 接口,这种做饭是不标准的,在应用程序未进入控制器或调用第三方插件(如富文本编辑器上传图片等,并不是所有第三方插件错误都监听不到)出问题时IExceptionFilter 接口是捕获不到错误的.
所以在Global.asax中捕获异常时很必要的,只需在IExceptionFilter 接口中把处理过的异常标记为已解决,Global.asax中是捕获不到此异常的。
MVC异常处理:
public class ExceptionFilter : FilterAttribute, IExceptionFilter
{
void IExceptionFilter.OnException(ExceptionContext filterContext)
{
var ex = filterContext.Exception;
var msg = ex.Message + " \r\n";
msg += "\r\r\r\r" + ex.InnerException + " \r\n";
msg += ex.StackTrace + " \r\n";
filterContext.HttpContext.Response.WriteFile("~/views/shared/error.html");
filterContext.HttpContext.Response.End();
filterContext.ExceptionHandled = true;//标记此异常为已解决
}
}
Global.asax 中异常处理:
protected void Application_Error(object sender, EventArgs e) { Exception ex = HttpContext.Current.Server.GetLastError(); if (ex.GetType() == typeof(HttpException)) return;//不捕获http异常 string errorMessage = BuildErrorMessage(ex); string msg = "--------------------header---------------------------------- \r\n"; msg += DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + " \r\n"; msg += BuildErrorMessage(ex) + " \r\n"; msg += ex.StackTrace + " \r\n"; msg += "----------------------footer-------------------------------\r\n"; string directory = Server.MapPath(string.Format("\\log\\OtherError\\{0}\\", DateTime.Now.ToString("yyyyMM"))); if (!System.IO.Directory.Exists(directory)) System.IO.Directory.CreateDirectory(directory); System.IO.File.AppendAllText(directory + DateTime.Now.ToString("yyyyMMdd") + ".log", msg + Environment.NewLine, System.Text.Encoding.Default); Server.ClearError();//清楚解决的异常 } private string BuildErrorMessage(Exception ex) { while (ex.InnerException != null) { ex = ex.InnerException; } return ex.Message; }