学习MVC不久,看到公司的项目里有日志记录功能,出于自己的原因一直没有看看是如何实现的,后来看了个学习视频和一些博文,才发现采用MVC里的过滤器 Filter 可以很容易实现,比较常见也很容易的做法就是继承 IActionFilter,IExceptionFilter 接口,然后实现里面的方法即可。

下面看一下代码,这是公司项目的一段代码,主要是将项目中出现的异常记录在 每天的txt日志文件里。当然实现日志的方法有很多种,这个只是其中一种,如果出现了IO错误,这种方法就不好说啦。

publicclassAppHandleErrorAttribute:FilterAttribute,IExceptionFilter{publicvoidOnException(ExceptionContextfilterContext){//System.Web.Mvc.ExceptionContextif(!filterContext.ExceptionHandled){//如果已经自己写了trycatch,那么可不用记录日志vards=(System.Web.Configuration.CompilationSection)System.Configuration.ConfigurationManager.GetSection("system.web/compilation");if(ds.Debug){//创建相关文件,并写入异常记录vardir=System.Web.HttpContext.Current.Server.MapPath("~")+@"\log\";if(!System.IO.Directory.Exists(dir)){System.IO.Directory.CreateDirectory(dir);}varpath=dir+DateTime.Now.ToString("yyyyMMdd")+"_site.txt";using(System.IO.StreamWritersw=newSystem.IO.StreamWriter(path,true)){vardataException=filterContext.Exception;varmessage=dataException.Message;sw.WriteLine();sw.WriteLine("-----------------"+DateTime.Now.ToString("HH:mm:ss")+"-----------------");sw.WriteLine(message);sw.WriteLine("Message:"+dataException.Message);sw.WriteLine("StackTrace:"+dataException.StackTrace.ToString());sw.Flush();sw.Close();}}filterContext.ExceptionHandled=true;//异常已经处理,程序可以不用在处理一遍//varlink=newUrlHelper(filterContext.RequestContext).Action("Index","CustomError");//filterContext.Result=newRedirectResult(link);//filterContext.Result=newContentResult(){Content="<center>网络连接异常,请<ahref='javascript:;'onclick='location.reload()'>刷新</a>重试</cener>",ContentType="text/html"};filterContext.Result=newContentResult(){Content="<center>当前网络发生故障,请刷新页面重试(点击<ahref='javascript:;'onclick='location.reload()'>刷新</a>)</cener>",ContentType="text/html"};}}}

上边这段代码很简单,如果只是单纯记录某一个Action的Exception,那么调用方法如下

[AppHandleError]publicActionResultxxAction(){returnView();}

如果是全局的设置,那么就要在项目的Global.ascx 里面加上这么一段话,注册 自定义的Filter

publicstaticvoidRegisterGlobalFilters(GlobalFilterCollectionfilters){filters.Add(newAppHandleErrorAttribute());}protectedvoidApplication_Start(){//AreaRegistration.RegisterAllAreas();//调用注册方法RegisterGlobalFilters(GlobalFilters.Filters);//RegisterRoutes(RouteTable.Routes);}

下面进入实战Demo


1.编写AppHandleErrorAttribute,代码已经贴出

2.在需要记录异常的Action上添加这个属性

[AppHandleError]publicActionResultIndex(){thrownewException("记录日志的内容");returnView();}

先看一下没加 这个过滤器的页面,很明显黄页:

下面是添加过滤器的运行效果:

那么这个页面就是错误处理页了,我这里是输出的内容,也可以将filterContext.Result 设置成为ViewResult,或者跳转到新的错误页面。再看一下日志记录:

可以看到,异常日志已经添加到相关的txt日志文件里面。


说明:如果在Global里面增加了项目配置,那么在Action上就不用标注这个过滤器,所有未经过Try catch的异常都可以捕获处理,代码,图略。


所以,try catch不是什么情况下都适用,如果不影响重要业务的情况下,可以使用try catch来处理业务,如果是比较重大的错误,就需要日志记录了。今天就到这里吧,第一次写这种博文,也算是自己的学习感想。有不足或者更好的方法欢迎批评指出。