.NET MVC HandleErrorAttribute可自动获取500错误并跳转Error.cshtml页面,前提条件webconfig页面需要在 <system.web>节点中添加<customErrors mode="On"/>。
首先在App_Start目录添加类FilterConfig
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomHandleErrorAttribute()); } }
然后在Global.asax中注册
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); log4net.Config.XmlConfigurator.Configure(); } }
一般创建项目时这些都会自动创建(当然配置文件需要手动添加),当然可以创建自己的异常处理类然后再过滤器中添加(替换默认的异常处理类即可),在自定义异常处理类中可以添加错误日志
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class CustomHandleErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { SaveExceptionAndError(filterContext); base.OnException(filterContext); } /// <summary> /// 写入错误日志 /// </summary> /// <param name="exceptionContext"></param> private void SaveExceptionAndError(ExceptionContext exceptionContext) { string errortime = string.Empty; string erroraddr = string.Empty; string errorinfo = string.Empty; string errorsource = string.Empty; string errortrace = string.Empty; errortime = "发生时间: " + System.DateTime.Now.ToString(); erroraddr = "异常位置: " + exceptionContext.RequestContext.HttpContext.Request.Url.ToString(); errorinfo = "异常信息: " + exceptionContext.Exception.Message; errorsource = "错误源:" + exceptionContext.Exception.Source; errortrace = "堆栈信息:" + exceptionContext.Exception.StackTrace; //独占方式,因为文件只能由一个进程写入. System.IO.StreamWriter writer = null; try { lock (this) { // 写入日志 string year = DateTime.Now.Year.ToString(); string month = DateTime.Now.Month.ToString(); string path = string.Empty; string filename = DateTime.Now.Day.ToString() + ".log"; path = exceptionContext.RequestContext.HttpContext.Server.MapPath("~/ErrorLogs/") + year + "/" + month; //如果目录不存在则创建 if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } System.IO.FileInfo file = new System.IO.FileInfo(path + "/" + filename); writer = new System.IO.StreamWriter(file.FullName, true);//文件不存在就创建,true表示追加 writer.WriteLine("用户IP:" + exceptionContext.RequestContext.HttpContext.Request.UserHostAddress); writer.WriteLine(errortime); writer.WriteLine(erroraddr); writer.WriteLine(errorinfo); writer.WriteLine(errorsource); writer.WriteLine(errortrace); writer.WriteLine("--------------------------------------------------------------------------------------"); //writer.Close(); } } finally { if (writer != null) writer.Close(); } } }
Error视图修改
@model System.Web.Mvc.HandleErrorInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="robots" content="noindex,nofollow"> <title>错误</title> <style> .wrap { margin: 150px auto; width: 450px; font-size: 14px; font-family: 'helvetica neue',tahoma,arial,'hiragino sans gb','microsoft yahei','Simsun',sans-serif; background-color: #fff; color: #808080; min-height: 100px; padding-top: 15px } .wrap table { width: 90%; margin: auto } td { text-align: left; padding: 2px 10px; vertical-align: top } td.header { font-size: 22px; padding-bottom: 10px; color: #000; } td.check-info { padding-top: 20px; } a { color: #328ce5; text-decoration: none; } a:hover { text-decoration: underline; } </style> </head> <body> <div class="wrap"> <table> <tr> <td rowspan="5" style=""><img src="~/Content/Images/warning_pic.jpg" alt="warning" width="70px"></td> <td class="header">抱歉!处理你的请求时出错</td> </tr> <tr> <td id="td_info"> 错误信息:@(Model.Exception.InnerException!=null?Model.Exception.InnerException.Message:Model.Exception.Message) </td> </tr> </table> </div> </body> </html>