要在ASP.NET中處理好自定義錯誤(Custom Errors)首先要拋棄使用web.config\customErrors。
<customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm">
<error statusCode="404" redirect="/error/404.htm" />
</customErrors>
使用web.config\customErrors最大的一個缺點是在顯示自定義錯誤頁面時會重定向:
http://www.cnblogs.com/error/error.htm?aspxerrorpath=/cmt/p/3789549.html
這會帶來2個麻煩:
1. 會造成用戶反饋問題時提供的是重定向后的URL。
2. 會造成用戶無法通過刷新瀏覽器進行重試,或者問題解決后通過刷新瀏覽器恢復正常。
我們目前想到的最佳處理方式是在Global.asax.cs的Application_Error中進行處理。
代碼如下:
protected void Application_Error(Object sender, EventArgs e) { Exception lastError = Server.GetLastError(); if (lastError != null) { if (lastError is HttpException) { if (((HttpException)lastError).ErrorCode == 404) { Response.StatusCode = 404; Server.ClearError(); return; } } CNBlogs.Infrastructure.Logging.Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
由于我們在IIS中指定了404/500錯誤的自定義錯誤頁面,所以這里只需要返回狀態碼(需要IIS 7.0以上)。
這樣處理后,還可以方便地在顯示自定義錯誤之前記錄到log4net日志。
另外需要注意的是一定要Server.ClearError(),不然ASP.NET會根據web.config\customErrors進行繼續處理(代碼中的自定義錯誤處理就會失效),錯誤信息也會被記錄到Windows日志(既然我們已經記錄到了log4net日志,就沒必要再記錄到Windows日志)。
你也許會問,幾行代碼就能解決的如此簡單的問題,值得興師動眾寫篇博客還要發在首頁?
值!因為之前我們沒有認真對待這個地方的問題,多次為此付出了代價。也許園子里還有人沒有注意這個地方的問題。
踩自己的坑,寫自己的博客,然后讓別人無坑可踩,我想這也是寫博客的一個價值體現吧。
【更新】
根據@NatureSexy的建議,改進了代碼:
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { var httpError = lastError as HttpException; if (httpError != null && httpError.ErrorCode == 404) { Response.StatusCode = 404; Server.ClearError(); return; } CNBlogs.Infrastructure.Logging.Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
【2014年12月27日更新】
Application_Error代碼更新,之前的代碼中沒有處理ASP.NET的400錯誤情況。
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { var httpError = lastError as HttpException; if (httpError != null) { //ASP.NET的400與404錯誤不記錄日志,并都以自定義404頁面響應 var httpCode = httpError.GetHttpCode(); if (httpCode == 400 || httpCode == 404) { Response.StatusCode = 404;//在IIS中配置自定義404頁面 Server.ClearError(); return; } Logger.Default.Error("Application_Error_" + httpCode, httpError); } //對于路徑錯誤不記錄日志,并都以自定義404頁面響應 if (lastError.TargetSite.ReflectedType == typeof(System.IO.Path)) { Response.StatusCode = 404; Server.ClearError(); return; } Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
注:如果用的是MVC,需要注釋下面的代碼:
//filters.Add(new HandleErrorAttribute());
文章列表
留言列表