學(xué)習(xí)MVC不久,看到公司的項(xiàng)目里有日志記錄功能,出于自己的原因一直沒(méi)有看看是如何實(shí)現(xiàn)的,后來(lái)看了個(gè)學(xué)習(xí)視頻和一些博文,才發(fā)現(xiàn)采用MVC里的過(guò)濾器 Filter 可以很容易實(shí)現(xiàn),比較常見(jiàn)也很容易的做法就是繼承 IActionFilter,IExceptionFilter 接口,然后實(shí)現(xiàn)里面的方法即可。
我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、祿勸ssl等。為上1000+企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的祿勸網(wǎng)站制作公司
下面看一下代碼,這是公司項(xiàng)目的一段代碼,主要是將項(xiàng)目中出現(xiàn)的異常記錄在 每天的txt日志文件里。當(dāng)然實(shí)現(xiàn)日志的方法有很多種,這個(gè)只是其中一種,如果出現(xiàn)了IO錯(cuò)誤,這種方法就不好說(shuō)啦。
public class AppHandleErrorAttribute : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { //System.Web.Mvc.ExceptionContext if (!filterContext.ExceptionHandled ) { //如果已經(jīng)自己寫(xiě)了try catch,那么可不用記錄日志 var ds = (System.Web.Configuration.CompilationSection)System.Configuration.ConfigurationManager.GetSection("system.web/compilation"); if (ds.Debug) { //創(chuàng)建相關(guān)文件,并寫(xiě)入異常記錄 var dir = System.Web.HttpContext.Current.Server.MapPath("~") + @"\log\"; if (!System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); } var path = dir + DateTime.Now.ToString("yyyyMMdd") + "_site.txt"; using (System.IO.StreamWriter sw = new System.IO.StreamWriter(path, true)) { var dataException = filterContext.Exception; var message = 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;//異常已經(jīng)處理,程序可以不用在處理一遍 //var link = new UrlHelper(filterContext.RequestContext).Action("Index", "CustomError"); //filterContext.Result = new RedirectResult(link); //filterContext.Result = new ContentResult() { Content = "網(wǎng)絡(luò)連接異常,請(qǐng)刷新重試", ContentType = "text/html" }; filterContext.Result = new ContentResult() { Content = " 當(dāng)前網(wǎng)絡(luò)發(fā)生故障,請(qǐng)刷新頁(yè)面重試(點(diǎn)擊刷新)", ContentType = "text/html" }; } } }
上邊這段代碼很簡(jiǎn)單,如果只是單純記錄某一個(gè)Action的Exception,那么調(diào)用方法如下
[AppHandleError] public ActionResult xxAction() { return View(); }
如果是全局的設(shè)置,那么就要在項(xiàng)目的Global.ascx 里面加上這么一段話(huà),注冊(cè) 自定義的Filter
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new AppHandleErrorAttribute()); } protected void Application_Start() { // AreaRegistration.RegisterAllAreas(); // 調(diào)用注冊(cè)方法 RegisterGlobalFilters(GlobalFilters.Filters); // RegisterRoutes(RouteTable.Routes); }
下面進(jìn)入實(shí)戰(zhàn)Demo
1.編寫(xiě)AppHandleErrorAttribute,代碼已經(jīng)貼出
2.在需要記錄異常的Action上添加這個(gè)屬性
[AppHandleError] public ActionResult Index() { throw new Exception("記錄日志的內(nèi)容"); return View(); }
先看一下沒(méi)加 這個(gè)過(guò)濾器的頁(yè)面,很明顯黃頁(yè):
下面是添加過(guò)濾器的運(yùn)行效果:
那么這個(gè)頁(yè)面就是錯(cuò)誤處理頁(yè)了,我這里是輸出的內(nèi)容,也可以將filterContext.Result 設(shè)置成為ViewResult,或者跳轉(zhuǎn)到新的錯(cuò)誤頁(yè)面。再看一下日志記錄:
可以看到,異常日志已經(jīng)添加到相關(guān)的txt日志文件里面。
說(shuō)明:如果在Global里面增加了項(xiàng)目配置,那么在Action上就不用標(biāo)注這個(gè)過(guò)濾器,所有未經(jīng)過(guò)Try catch的異常都可以捕獲處理,代碼,圖略。
所以,try catch不是什么情況下都適用,如果不影響重要業(yè)務(wù)的情況下,可以使用try catch來(lái)處理業(yè)務(wù),如果是比較重大的錯(cuò)誤,就需要日志記錄了。今天就到這里吧,第一次寫(xiě)這種博文,也算是自己的學(xué)習(xí)感想。有不足或者更好的方法歡迎批評(píng)指出。