ASP.NET全局錯誤處理和異常日志記錄以及IIS配置自定義錯誤頁面


應用場景和使用目的

很多時候,我們在訪問頁面的時候,由於程序異常、系統崩潰會導致出現黃頁。在通常的情況下,黃頁對於我們來說,幫助是極大的,因為它可以幫助我們知道問題根源,甚至是哪一行代碼出現了錯誤。但這對於用戶是非常可怕的,因為用戶不知道發生了什么,也無法了解黃頁給出的內容。甚至,如果我們遇到一些不友好的人,他們會拿這些內容大做文章,對我們網站產生威脅。

那我們如何在程序異常、系統崩潰時,不會出現黃頁,並且還可以給出一些更加友好的提示呢?甚至在我們需要的時候,可以收集這些異常信息,並加以分析,能夠迅速定位錯誤來源,解決問題呢?以下給出了三種解決辦法。

使用customErrors,用戶自定義錯誤

 在Web.config的<system.web>節點下添加

1 <customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm">    
2   <error statusCode="404" redirect="/error/404.html" />
3   <error statusCode="403" redirect="/error/403.html" />
4   <error statusCode="500" redirect="/error/500.html" />
5 </customErrors>

mode 指定啟用、禁用或僅對遠程客戶端顯示自定義錯誤。mode=RemoteOnly為默認值,指定僅向遠程客戶端端顯示自定義錯誤,並向本地主機顯示 ASP.NET 錯誤。 當mode=on時,如果沒有指定 defaultRedirect,用戶將看到一般性錯誤。當mode=off時,將顯示詳細的錯誤。

defaultRedirect 指定發生錯誤時瀏覽器指向的默認 URL。如果沒有指定 defaultRedirect,則會顯示一般性錯誤。

statusCode 指定導致重定向至錯誤頁的 HTTP 狀態碼。

Redirect 向客戶端提供錯誤信息的錯誤頁。

使用httpErrors,覆蓋customErrors

強烈建議,為什么?在默認情況下,customErrors跳轉自定義錯誤頁時會進行302重定向。當我們請求到一個錯誤頁事,頁面會先進行302重定向,然后返回200OK。對於用戶來說,這個是完全沒有問題的,因為做到了友好的用戶體驗。但對於爬蟲,它會認為這是一個錯誤頁面,比如404,並且會將其錄入。而且,customErrors每次重定向后都會帶上一個小尾巴aspxerrorpath,比如http://yoursite.com/error/404.html?aspxerrorpath=/exceptionpageurl。還有一些時候,由於customErrors屬於托管環境下的自定義配置,當請求尚未到達ASP.NET管線時,customErrors是不能發揮其作用的,所以使用httpErrors也包括同時也可以處理請求在未到達ASP.NET管線同樣也能捕捉到異常。

在Web.config的<configuration>/<system.webServer>節點下添加

1 <httpErrors errorMode="Custom" existingResponse="Replace" defaultResponseMode="ExecuteURL">
2    <remove statusCode="403" subStatusCode="-1"/>
3    <remove statusCode="404" subStatusCode="-1"/>
4    <remove statusCode="500" subStatusCode="-1"/>
5    <error statusCode="403" path="/403.html" prefixLanguageFilePath="" responseMode="ExecuteURL"/>
6    <error statusCode="404" path="/404.html" prefixLanguageFilePath="" responseMode="ExecuteURL"/>
7    <error statusCode="500" path="/500.html" prefixLanguageFilePath="" responseMode="ExecuteURL"/>
8  </httpErrors>

 詳情參見http://www.iis.net/configreference/system.webserver/httperrors

 

在Global.asax中的Application_Error方法中統一處理錯誤頁,並記錄日志

前兩種方式都是可以做到自定義錯誤頁面,但唯獨不能自定義記錄日志,而這種方式則可以同時滿足這兩種需求。

 1   protected void Application_Error(Object sender, EventArgs e)  2  {  3       Exception lastError = Server.GetLastError();  4   
 5       if (lastError != null)  6  {  7           if (lastError is HttpException)  8  {  9                   Server.ClearError(); // 清除錯誤狀態
10                   Server.Transfer($"/error/{Response.StatusCode}.html"); // 跳轉指定友好體驗的頁面 11                   // 可同時使用兩種方式記錄日志 12                   // 第一種 使用log4net 13                   // 第二種 使用數據庫
14  } 15  } 16  }

log4net記錄異常日志,園子里已經有很多文章詳細講解了,在這里就不贅述了。數據庫記錄異常日志,要說明一下表設計,因為要考慮到可能不是只有這一個地方要記錄異常日志,還有比如在Application_BeginRequest,Application_EndRequest等等。所以表設計的字段應該含有當前所在上下文,所報異常源,異常信息等字段。這樣會在我們日后快速定位錯誤,排查異常起到很重要的作用。

這里還要注意一下是Server.Transfer不會更改URL,如果需要更改URL可使用Response.Redirect進行跳轉。

總結

customErrors由於對SEO造成不利,所以現在已經不建議使用了。

httpErrros不會造成302重定向,同時能捕獲到未到達ASP.NET管線的異常請求,但不能自定義異常日志。

Application_Error同時可以自定義錯誤頁面,也可自定義日志。但需要注意的一點,Application_Error由於也位於托管環境,所以同時也無法捕捉到未到達ASP.NET管線的異常請求。

因此,根據三種解決辦法,首推httpErrors和Application_Error。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM