通常,當系統發生錯誤時,我們會不希望User只看到一般的自定的錯誤訊息,且真正完整的錯誤訊息可透過寫入Log檔或寄mail的方式提供給開發人員除錯。
以下是簡單的應用方式:Step 1. 在 Web.config 設定錯誤導向頁面
<customErrors mode="RemoteOnly" defaultRedirect="HttpErrorPage.aspx"/>
Step 2. HttpErrorPage.aspx 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | < %@ Page Language ="C#" % > <script runat= "server" > protected HttpException ex = null; protected void Page_Load(object sender, EventArgs e) { ex = (HttpException)Server.GetLastError(); int httpCode = ex.GetHttpCode(); // Log the exception and notify system operators ExceptionUtility.LogException(ex, "Caught in HttpErrorPage" ); ExceptionUtility.NotifySystemOps(ex, "Caught in HttpErrorPage" ); // Fill the page fields exMessage.Text = ex.Message; if (Request.IsLocal) exTrace.Text = ex.StackTrace; if (ex.Message.IndexOf( "登入錯誤" ) == -1) TitlePanel.Visible = true; // Show Inner Exception fields for local access if (ex.InnerException != null) { if (Request.IsLocal) innerTrace.Text = ex.InnerException.StackTrace; InnerErrorPanel.Visible = Request.IsLocal; innerMessage.Text = string.Format( "HTTP {0}: {1}" , httpCode, ex.InnerException.Message); } // Show Trace for local access exTrace.Visible = Request.IsLocal; // Clear the error from the server Server.ClearError(); hidPage.Value = ResolveUrl( "~" ) + "Default.aspx" ; } </script> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > <html> <head id = "Head1" runat= "server" > <title> Http Error Page </title> <base target = '_self' /> <script language =javascript > function myRedirect() { window.open(document.getElementById( "hidPage" ).value); window.top.opener = null; window.opener = null; void (window.open( '' , '_parent' , '' )); window.close(); } </script> <style type = "text/css" > h3, h4 { color:#4465A2; } </style> </head> <body> <form id = "form1" runat= "server" > <br /> <div style = "border: 1px solid #0000FF; background-color: #DAEBFC" > <h3> A problem has occurred in the web site. </h3> < asp:Panel ID = "TitlePanel" runat= "server" Visible= "false" > <h4> 網頁發生錯誤,已通知系統管理員,請您重新登入系統後再試一次。 <br /> 造成您的不便,敬請見諒! </h4> </ asp:Panel > < asp:Panel ID = "InnerErrorPanel" runat= "server" Visible= "false" > < asp: Label ID = "innerMessage" runat= "server" Font-Bold= "true" Font-Size= "Large" /><br /> <pre> < asp: Label ID = "innerTrace" runat= "server" /> </pre> </ asp:Panel > <input type = "hidden" id = "hidPage" runat= "server" /> Error Message: <br /><br /> < asp: Label ID = "exMessage" runat= "server" Font-Bold= "true" Font-Size= "Large" ForeColor= "#990000" /> <pre> < asp: Label ID = "exTrace" runat= "server" Visible= "false" /> </pre> <hr /><br /> Return to the <span style = "CURSOR: hand; color:blue; font-size:12pt;" onclick = "myRedirect()" ><b><u> Default Page </u></b></span> <br /><br /> </div> </form> </body> </html> |
Step 3. ExceptionUtility 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | using System; using System.IO; using System.Web; // Create our own utility for exceptions public sealed class ExceptionUtility{ private const string ExceptMailTo = "xx@xx.com" ; private const string mailSubject = "【xxx system】- Exception 系統通知" ; // All methods are static, so this can be private private ExceptionUtility() { } // Log an Exception public static void LogException(Exception exc, string source) { // Include enterprise logic for logging exceptions // Get the absolute path to the log file string logFile = string .Format( "~/App_Data/ErrorLog_{0}.txt" , DateTime.Now.Year.ToString()+ DateTime.Now.Month.ToString().PadLeft( 2 , "0" .ToCharArray()[ 0 ])); logFile = HttpContext.Current.Server.MapPath(logFile); // Open the log file for append and write the log StreamWriter sw = new StreamWriter(logFile, true ); sw.WriteLine( "********** {0} **********" , DateTime.Now); if (exc.InnerException != null ) { if (exc is HttpException) { sw.Write( "HttpCode: " ); sw.WriteLine(((HttpException)exc).GetHttpCode()); } sw.Write( "Inner Exception Type: " ); sw.WriteLine(exc.InnerException.GetType().ToString()); sw.Write( "Inner Exception: " ); sw.WriteLine(exc.InnerException.Message); sw.Write( "Inner Source: " ); sw.WriteLine(exc.InnerException.Source); if (exc.InnerException.StackTrace != null ) { sw.WriteLine( "Inner Stack Trace: " ); sw.WriteLine(exc.InnerException.StackTrace); } } sw.Write( "Exception Type: " ); sw.WriteLine(exc.GetType().ToString()); sw.WriteLine( "Exception: " + exc.Message); sw.WriteLine( "Source: " + source); sw.WriteLine( "Stack Trace: " ); if (exc.StackTrace != null ) { sw.WriteLine(exc.StackTrace); sw.WriteLine(); } sw.Close(); } // Notify System Operators about an exception public static void NotifySystemOps(Exception exc, string source) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append( string .Format( "********** {0} **********" , DateTime.Now)); sb.Append( "<br> " ); sb.Append( "<table width=\"500\" border=\"1\" cellPadding=\"3\" cellSpacing=\"0\" style=\"\"> " ); if (exc.InnerException != null ) { if (exc is HttpException) { sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">HttpCode: </td>" ); sb.Append( " <td>" + ((HttpException)exc).GetHttpCode().ToString() + "</td></tr>" ); } sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Inner Exception Type: </td>" ); sb.Append( " <td>" + exc.InnerException.GetType().ToString() + "</td></tr>" ); sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Inner Exception: </td>" ); sb.Append( " <td>" + exc.InnerException.Message + "</td></tr>" ); sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Inner Source: </td>" ); sb.Append( " <td>" + exc.InnerException.Source + "</td></tr>" ); if (exc.InnerException.StackTrace != null ) { sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Inner Stack Trace: </td>" ); sb.Append( " <td>" + exc.InnerException.StackTrace + "</td></tr>" ); } } sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Exception Type: </td>" ); sb.Append( " <td>" + exc.GetType().ToString() + "</td></tr>" ); sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Exception: </td>" ); sb.Append( " <td>" + exc.Message + "</td></tr>" ); sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Source: </td>" ); sb.Append( " <td>" + source + "</td></tr>" ); sb.Append( " <tr > <td style=\"BACKGROUND-COLOR: #445a83;padding: 1px; border: 1px solid; color: #FFFFFF;\">Stack Trace: </td>" ); sb.Append( " <td>" + (exc.StackTrace != null ? exc.StackTrace: "" ) + "</td></tr>" ); sb.Append( "</table>" ); someSendMailClass.sendMail(ExceptMailTo, "" , mailSubject, sb.ToString()); }} |
Log內容可自行擴充修改,如增加User name , User email, User IP...