MVC HandleErrorAttribute异常过滤器

.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>  

 

posted @ 2019-03-15 16:19  sean-日积月累  阅读(347)  评论(0编辑  收藏  举报