前言:
在项目中我们都会对项目里的异常进行处理,一方面是为了用户交互性更好,另一方面也为我们的后期的维护提供了便利。在项目的过程中也许我们更多的是用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的这个特性来实现的,在我们的自己定义的类中重写HandleErrorAttribute的OnException()方法来实现我们的业务。
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中的全局异常捕获和自定义异常捕获就给大家简单的介绍完了!
大家有什么更简洁方式,请留言!
结尾:分享:
真实是人生的命脉,是一切价值的根基。 —— 德莱塞