1. 程式人生 > >asp.net中當伺服器出錯時顯示指定的錯誤頁面

asp.net中當伺服器出錯時顯示指定的錯誤頁面

此篇文章描述了當異常再ASP.NET中發生時怎樣使用C#.NET程式碼去攔截和相應異常。ASP.NET在異常處理方面比傳統的ASP更優越。在ASP.NET中,允許在應用程式的各個層面中處理異常。
ASP.NET的新特性
ASP.NET為捕獲並處理異常提供了更多的便利。在傳統的ASP程式中,我們用“On Error Resume Next”(或Jscript的Try-catch)來處理異常。另一個方法是如果你執行IIS5.0的話,使用ASPError物件去建立一個自定義的錯誤頁面,然而,這些方法有他們的侷限性.
當一個ASP.NET應用程式出錯的時候,ASP.NET提供一些能夠捕捉和處理這些異常的辦法。ASPNET提供三個主要的方法允許你捕捉和處理錯誤,當錯誤發生時:Page_Error事件 Application_Error事件,和應用程式配置檔案(Web.config)
    此篇文章旨在演示怎樣在你的ASPNET應用程式使用這三個新功能。但是此篇文章不對其他的異常處理方式進行描述,如:try-catch-finally,和CLR(Common Language Runtime)異常處理系統。
怎樣使用Page_Error事件
Page_Error事件提供一種攔截頁面層異常的方法.你可以簡單的顯示錯誤資訊(見示例),或者記入日誌又或者執行其他的動作.
注意:這個例子演示了怎樣在瀏覽器中顯示詳細的錯誤資訊.需要注意的是顯示詳細的錯誤資訊給使用者不是一個好辦法,特別是當應用程式在Internet上執行的時候.更適合的方法是顯示一個資訊給使用者通知他們一個錯誤發生,然後將錯誤的詳細資訊記入日誌.
這個例子丟擲一個null exception,強制異常出現在Page_Load事件中.按照如下步驟建立測試Page_Error事件的頁面.
按照如下的步驟在您的專案中建立一個名為PageEvent.aspx的新檔案:

開啟VisualStudio.NET

在解決方案瀏覽器中,右擊專案節點,指向新增,然後點選新增新窗體.

在名稱文字框中,輸入PageEven.aspx,然後點選Open.

將下面的程式碼新增到PageEvent.aspx中:

<script language=C# runat="server">
void Page_Load(object sender, System.EventArgs e)
{
     throw(new ArgumentNullException());
}
public void Page_Error(object sender,EventArgs e)
{
     Exception objErr = Server.GetLastError().GetBaseException();
     string err =   "<b>Error Caught in Page_Error event</b><hr><br>" + 
                   "<br><b>Error in: </b>" + Request.Url.ToString() +
                    "<br><b>Error Message: </b>" + objErr.Message.ToString()+
                   "<br><b>Stack Trace:</b><br>" + 
                       objErr.StackTrace.ToString();
     Response.Write(err.ToString());
     Server.ClearError();
}
</script> 

在檔案選單中,單擊儲存.

右擊這個頁面,然後單擊在瀏覽器中瀏覽以執行此頁面.異常會按照我們預想的丟擲,並且被上面的程式碼所處理.

注意:你可能注意到這個程式碼呼叫了Server.ClearError方法.這個方法阻止異常傳遞到Application_Error事件中.
此外,你應該注意@Page標籤的Inherits屬性。如果Inherits被設定,你應該首先編譯整個專案,否則在瀏覽此頁面的時候你將收到如下錯誤資訊: 'Project.PageEvent' is not a valid type
怎樣使用Application_Error事件
與Page_Error相似,你可以使用Application_Error事件在你的應用程式中攔截異常由於此事件的應用程式級作用範圍,你可以將錯誤資訊記錄入日誌,或者處理其它的可能發生的應用程式級別的異常.
    下述示例源自前述的Page_Error事件程式碼,並且當Page_Load事件中的異常沒有被Page_Error事件處理的時候被激發.Application_Error事件被指定在Global.asax檔案中.為簡化,下述步驟建立了一個新的頁面並且丟擲一個異常,在Global.asax檔案中Application_Error事件裡攔截和處理這個異常,將錯誤寫入日誌.下述步驟演示了怎樣使用Application_Error事件:
在你的專案中新增一個名為AppEvent.aspx的檔案.
將下述程式碼新增到AppEvent.aspx檔案中: 
    <script language=C# runat="server">
       void Page_Load(object sender, System.EventArgs e)
       {
             throw(new ArgumentNullException());
        }
</script> 
  <script language=C# runat="server">
  void Page_Load(object sender, System.EventArgs e)
        {
               throw(new ArgumentNullException());
      }

</script>

儲存.

將Application_Error新增到Global.asax檔案中以攔截在ApEvent.aspx檔案中丟擲的異常.注意,你必須在Global.asax檔案中新增對System.Diagnostics名稱空間的引用才能使用事件日誌.
將如下程式碼新增到Global.asax 檔案中:

using System.Diagnostics;
protected void Application_Error(object sender, EventArgs e)

{
Exception objErr = Server.GetLastError().GetBaseException();
string err =   "Error Caught in Application_Error event/n" +
                 "Error in: " + Request.Url.ToString() +
                  "/nError Message:" + objErr.Message.ToString()+ 
                  "/nStack Trace:" + objErr.StackTrace.ToString();
 EventLog.WriteEntry("Sample_WebApp",err,EventLogEntryType.Error);
  Server.ClearError();
  //additional actions...

儲存.

編譯.

執行

怎樣使用Web.config 檔案
如果你沒有在呼叫Server.ClearError方法,或者在Page_Error或Application_Error方法中捕獲異常,那麼異常會按照Web.config檔案中<customErrors>區段的使者被處理.在<customErrors>區段中,你可以指定一個預設的錯誤導向頁面(defaultRedirect)或指定一個特定的HTTP頁面錯誤程式碼.你可以使用此方法自定義使用者接收到的錯誤程式碼.

如果錯誤在應用程式的各個級別都沒有被捕獲,那麼自定義頁面就會顯示.此節說明了怎樣編輯Global.asax檔案以保證Server.ClearError方法不會被呼叫.因此,異常才會被Web.congif檔案作為最後一環異常處理方法被捕捉.
開啟上一個例子的Global.asax 檔案.
註釋掉Server.ClearError 行.
儲存,你的程式碼應該看起來像下面的程式碼:
using System.Diagnostics;
protected void Application_Error(object sender, EventArgs e)
{
   Exception objErr = Server.GetLastError().GetBaseException();
   string err =   "Error Caught in Application_Error event/n" +
                 "Error in: " + Request.Url.ToString() +
                 "/nError Message:" + objErr.Message.ToString() + 
                  "/nStack Trace:" + objErr.StackTrace.ToString();
    EventLog.WriteEntry("Sample_WebApp",err,EventLogEntryType.Error);
    //Server.ClearError();
  //additional actions...

新增下面的程式碼加入以此來將使用者重定向到自定義的頁面:
<customErrors defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On">
</customErrors>
注意: 你必須修改defaultRedirect 屬性以關聯你自己的應用程式頁面..
由於在此層面被攔截的異常被髮送到一個預設的錯誤頁面,你必須建立一個錯誤頁面並且命名為ErrorStatus.htm. 請記住你使用此方法是在控制那些能夠呈現給使用者的東西,所以這個例子使用了一個html檔案充當錯誤頁面。將下面的程式碼新增到ErrorStatus.htm檔案中.<HTML><HEAD><TITLE></TITLE>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
</HEAD>
<BODY>
<b>Custom Error page!</b>
<br>You have been redirected here from the &lt;customErrors&gt; section of the Web.config file.</BODY>  </HTML>
儲存,編譯專案,然後在瀏覽器中瀏覽AppEvent.aspx測試上述程式碼.注意當異常被丟擲的時候,你會被重定向到ErrorStatus.htm頁面
儘管你可以通過設定<customErrors>區段的defaultRedirect屬性來引用一個預設的錯誤頁面,你還可以指定當特定的HTTP程式碼的異常出現的時候使用者被導向的不同頁面.<error>子元素用來設定這個功能.例:
<customErrors defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On">
       <error statusCode="404" redirect="filenotfound.htm" />
</customErrors>
注意:這裡的defaultRedirect屬性設定的是HTML頁面.如果你想在一個aspx檔案中呼叫Server.GetLastError方法的話(像上面Page_Error和Application_Error的例子),你必須在重定向之前將異常儲存在Session變數中或其他合適的地方.
Notice that the <customErrors> section includes a mode attribute that is set to On. The mode attribute is used to control how the error redirection occurs. For example, if you are developing the application, you most likely want to see the actual ASP.NET error messages and do not want to be redirected to the more user-friendly error page. The mode attribute includes the following settings:
<customErrors>區段包括一個被設定為ON的Mode屬性.這個屬性是用來控制錯誤重定向的方式.舉個例子,如果你在開發一個Web應用程式,你可能希望看到實際的ASPENET錯誤資訊,而不希望被重定向到一個用好的錯誤頁面.這個屬性包括如下設定:
On: 未被處理的異常發生時將使用者重定向到defaultRedirect 屬性設定的頁面.多數用在產品.
Off: 使用者會開到詳細錯誤資訊,並且不會被重定向到指定的錯誤頁面.這個設定多數用在開發過程中..
RemoteOnly: 只有當本地計算機訪問的時候(localhost)才能獲得異常的詳細資訊.其它的使用者會被重定向到指定的錯誤頁面.主要用在處錯過程中.