1.注册自己的异常过滤器
在MVC类型的项目中App_Start文件夹下的FilterConfig文件中存在一个异常处理的过滤器,我们要将其改写文我们自己的异常处理过滤器。将我们自己定义的捕获异常的类注册到项目中,即告诉项目调用我们自己定义的方法 即在 FilterConfig作如下配置。在Global.asax中可知该过滤器在项目启动时已经启动。
- public class FilterConfig
- {
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)
- {
- //filters.Add(new HandleErrorAttribute());//原来的
-
- filters.Add(new MyExceptionAttribute()); //自己写的
- }
- }
2.捕获异常
构建一个MyExceptionAttribute类继承HandleErrorAttribute
在HandleErrorAttribute中存在一个public virtual void OnException(ExceptionContext filterContext);虚方法
在我们自己构建的类中重载该方法,用于捕获异常信息
- public class MyExceptionAttribute: HandleErrorAttribute
- {
- public static Queue<Exception> ExceptionQueue = new Queue<Exception>();//定义队列,一定要是静态的,静态才能共享
-
- /// <summary>
- /// 在该方法中捕获异常
- /// </summary>
- /// <param name="filterContext"></param>
- public override void OnException(ExceptionContext filterContext)
- {
- base.OnException(filterContext);
- Exception ex = filterContext.Exception;//捕获异常信息
-
- //将异常信息写入队列中
- ExceptionQueue.Enqueue(ex);
- //跳转到错误页面
- filterContext.HttpContext.Response.Redirect("/Errow.html");
-
- }
- }
3.将异常信息写入文本文件
在异常写入过程中要考虑并发问题,要利用生产者消费者模式考虑此问题,在将错误信息写入队列以后 在Global.ascx 的Application_Start()开辟一个线程将错误信息写入文件中,此线程从项目启动开始,一直扫描队列中是否有异常信息,有的话写入文件。
在项目中先建一个Log文件夹,在Global.ascx中Application_Start()修改成如下:
- protected void Application_Start()
- {
- //开启一个线程,查看异常队列
- string filePath = Server.MapPath("/Log/");
- ThreadPool.QueueUserWorkItem((a) =>
- {
- while(true)//线程不能结束,否则后面写到队列中的数据没法处理
- {
- if(MyExceptionAttribute.ExceptionQueue.Count()>0)
- {
- Exception ex = MyExceptionAttribute.ExceptionQueue.Dequeue();//出队列
- if(ex!=null)
- {
- string fullPath = filePath + DateTime.Now.ToString("yyy-MM-dd") + ".txt";
- File.AppendAllText(fullPath, ex.ToString());
- }
- else
- {
- Thread.Sleep(3000);
- }
- }
- else
- {
- Thread.Sleep(3000);//避免造成cpu空转
- }
- }
- },filePath);//WaitCallback是一个委托 执行一个线程就是执行一个方法
- AreaRegistration.RegisterAllAreas();
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- }