Asp.Net中MVC中的全局异常捕获以及自定义异常捕获

前言:

在项目中我们都会对项目里的异常进行处理,一方面是为了用户交互性更好,另一方面也为我们的后期的维护提供了便利。在项目的过程中也许我们更多的是用try{}catch{}进行捕获异常。在这里我给大家简单的介绍下我们在MVC中自带的一种捕获异常的机制,它就是:Asp.Net中MVC的全局异常捕获。


MVC中的全局异常捕获简介:

全局异常捕获是微软在VS中自带的一种机制。在Asp.Net的MVC中默认提供了一个异常过滤器HandleError特性,使用该特性可以极为方便的捕捉并处理控制器和操作抛出的异常,它会自动的检测在程序中运行的错误,并且拿到错误的相关信息。在Asp.Net的MVC中的只要网站抛出异常,都会触发Global.asax中Application_Error事件,这个方法就是用来捕获异常的,在这个代码里面我们可以添加我们的业务代码(一般就是记录错误的日志以及异常的处理)。

在MVC中还可以使用HandleErrorAttribute的特性标签来捕获异常,该特性主要用于具体操作方法上,在写项目中我们 一般很少用到。这里不给大家介绍了,大家想了解的话,百度就行了。


MVC中的自定义异常捕获简介:

在Asp.Net中不但可以用全局的异常捕获,微软也给我们提供了一种自定义的异常捕获,来满足我们的需求。当然在自定义的异常捕获中,我们底层还是用VS提供的HandleErrorAttribute的这个特性来实现的,在我们的自己定义的类中重写HandleErrorAttributeOnException()方法来实现我们的业务。


MVC全局异常捕获代码演示:

①:在Global.asax里添加Application_Error事件(注意:Application_Start外部添加这个方法

        protected void Application_Error(Object sender, EventArgs e)
        {
            Exception lastError = Server.GetLastError();//获取异常
            if (lastError != null)
            {
                //异常信息
                string strExceptionMessage = string.Empty;

                //对HTTP 404做额外处理,其他错误全部当成500服务器错误
                HttpException httpError = lastError as HttpException;
                if (httpError != null)
                {
                    //获取错误代码
                    int httpCode = httpError.GetHttpCode();
                    //获取异常信息
                    strExceptionMessage = httpError.Message;
                    if (httpCode == 400 || httpCode == 404)
                    {
                        Response.StatusCode = 404;
                        //跳转到指定的静态404信息页面
                        Response.WriteFile("~/404.html");
                        //一定要调用Server.ClearError()否则会触发错误详情页(就是黄页)
                        Server.ClearError();
                        return;
                    }
                }
                strExceptionMessage = lastError.Message;//得到错误信息,可以写到日志里

                /*-----------------------------------------------------
                 * 此处代码可根据需求进行日志记录,或者处理其他业务流程
                 * ---------------------------------------------------*/
                 /* 跳转到静态页面一定要用Response.WriteFile方法  */                
                
                //Response.StatusCode = 500;展示错误状态码
                Response.WriteFile("~/error.html");
                //一定要调用Server.ClearError()否则会触发错误详情页(就是黄页)
                Server.ClearError();
            }

        }

②:注销掉FilterConfig类里的filters.Add(new HandleErrorAttribute()),否则会默认自定义

③:在web.con.fig配置节<system.web>里添加配置,关闭自定义的模式,否则VS会默认开启

<customErrors mode="Off"></customErrors>
<!--注意大小写-->

④:在控制器里写错误的代码

运行结果:

注意重点;小心大坑,大坑!!!,我差点没出来!坑死我了

就是我们也按上面的步骤做了,为啥程序中断了,捕获不到异常。

这是因为在VS里有个中断异常处理,如果你的程序中有错误会直接让程序中断,这时我们的所用的异常处理就无法发挥作用了。

中断程序展示:

解决办法:

做完上一步的操作就能出现上面的效果了!

全局异常捕获演示完毕!


自定义异常捕获演示:

在自定义演示里我把程序中的错误写到日志里。

演示开始:

①:先自定义一个类,让这个类继承HandleErrorAttribute,并重写HandleErrorAttribute里的OnException方法

public class MyErrorAttribute : HandleErrorAttribute
    {
       
            //创建静态队列
            public static Queue<Exception> ExceptionQueue = new Queue<Exception>();
            public override void OnException(ExceptionContext filterContext)
            {
                //将异常信息写入队列中
                ExceptionQueue.Enqueue(filterContext.Exception);
                base.OnException(filterContext);
               filterContext.HttpContext.Response.Redirect("~/error.html");
            }
    }

②:在FilterConfig这个类里注销原先的注册的HandleErrorAttribute

③:在Global.asax的Application_Start里进行开启线程,把捕获的错误写成日志

 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            string errorFilePath = Server.MapPath("~/errorFile/");//文件夹路径
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    if (MyErrorAttribute.ExceptionQueue.Count > 0)
                    {
                        Exception ex = MyErrorAttribute.ExceptionQueue.Dequeue();
                        if (ex != null)
                        {
                            //将异常信息写到文件夹中,如果文件不存在则创建该文件
                            string fileName = DateTime.Now.ToString("yyyy-mm-dd");
                            File.AppendAllText(errorFilePath + fileName + ".txt", ex.ToString(), System.Text.Encoding.UTF8);
                        }
                        else
                        {
                            Thread.Sleep(500);
                        }
                    }
                    else
                    {
                        Thread.Sleep(500);
                    }
                }
            });
        }

④:在一个控制器写错误的代码:

注意:别忘了上面的那个坑

运行结果展示:

日志展示


 

到这里ASP.Net的MVC中的全局异常捕获和自定义异常捕获就给大家简单的介绍完了!

大家有什么更简洁方式,请留言!


结尾:分享:

真实是人生的命脉,是一切价值的根基。 —— 德莱塞

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值