2013-07-05 30 views
0

我在C#中編寫ASP.NET應用程序,我正在處理可能從其他文件拋出的異常。我有一個我編寫的C#類文件,其中包含執行SQL命令的方法,並且我希望在應用程序投入生產時防止出現可能的異常。從單獨的類文件在ASP.NET(C#)中的異常處理

這是SQL方法我寫的,我故意在拋出一個錯誤(從SqlData.cs):

public SqlConnection openConnection() 
{ 
     //Create an SQL connection 
     SqlConnection myConnection = new SqlConnection("My intentionally incorrect connection string"); 

     //Open the connection 
     try 
     { 
      myConnection.Open(); 
     } 
     catch (SqlException myAppEx) 
     { 
      throw new ApplicationException("There was an error opening the SQL database connection", myAppEx); 
     } 

     return myConnection; 
    } 

我把從我Default.aspx.cs該方法具有以下行文件代碼:

try 
{ 
    //The ReadDT method calls openConnection() in itself 
    dt = sqlData.ReadDT(query); 
} 
catch (ApplicationException exc) 
{ 
    throw exc; 
} 

我想實現頁面級的異常處理,其中,如果一個例外是當前頁面上提出應該在Page_Error事件方法被調用,如引here。這就是爲什麼我會捕獲從我的SqlData.cs類文件中拋出的異常,並重新拋出異常,以便服務器可以看到此異常。因此,Server.GetLastError()將不會返回null

由於實施here,我有一個單獨的錯誤頁面,顯示所有的異常信息。我Page_Error事件的方法如下:

private void Page_Error(object sender, EventArgs e) 
{ 
    Server.Transfer("ErrorPage.aspx?handler=Page_Error%20-%20Default.aspx", true); 
} 

從這裏用戶被重定向到我的ErrorPage.aspx和最初拋出的SqlException完美顯示。

問題 - 當我從SqlData.cs中捕獲異常並重新拋出異常時,會引發UnhandledException。如果我不在ReadDT方法調用中放置try catch塊,則會從我的SqlData.cs文件中引發相同的UnhandledException

跟蹤代碼:

  1. throw new ApplicationException("There was an error opening the SQL database connection", myAppEx);(這工作正常)
  2. 異常,然後捕獲並重新拋出(UnhandledException發生)
  3. Page_Error方法被調用,因爲它應該是,一切執行正確!

我希望我在回答自己時已經很清楚,我已經對異常和我的特殊問題進行了大量研究,並且我沒有找到答案。

感謝, 埃裏克

+0

所以你在這裏的總體目標是確保在發生異常時用戶會被重定向到一個錯誤頁面? – Arran

+0

全局文件中的'Application_Exception'怎麼樣? –

+0

收聽Shekhar ... global.aspx文件中有一個全局異常處理程序或任何它被稱爲...你可以使用這個(我有過去)重定向到一個自定義的錯誤頁面... –

回答

0

因此,我想出了通過代碼級異常處理的錯誤處理組合,並將用戶重定向到錯誤頁面,然後使用ELMAH記錄錯誤,以解決我的問題。

我現在直接在我的SqlData類文件中處理所有異常,以獲得最少但效率最高的代碼。我在我的SqlData類文件中有一個全局變量HttpResponse response,每當我在ASP.NET應用程序中創建類的新實例時,我都會填充它。所以從我的Main.aspx.cs文件我有類似:

private SQLData data; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    data = new SQLData(Response); 
    ... 
} 

如果我這樣做,我可以從我的類文件調用response.Redirect()用戶發送到我的錯誤頁面,我通過異常錯誤消息和查詢字符串中的異常類型,然後將其輸出到我的錯誤頁面中的用戶。這使我只能向用戶顯示非敏感信息。因此,例外情況已經處理完畢,ELMAH記錄了所有細節!

//Create an SQL connection 
SqlConnection myConnection = new SqlConnection("MyConnString"); 

//Open the connection 
try 
{ 
    myConnection.Open(); 
} 
catch (Exception ex) 
{ 
    //Manually log the exception in ELMAH 
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex); 
    //Redirect the user to the error page 
    response.Redirect("ErrorPage.aspx?ErrorMessage=" + ex.Message + "&ErrorType=SQLException", true); 
} 

return myConnection; 

然後我有我的錯誤頁面引導至elamh.axd頁面底部的鏈接顯示只有當你是管理員。在此頁面中,您可以查看堆棧跟蹤和其他敏感信息。

您可以在this頁面的底部找到有關ELMAH的信息,也可以在ASP.NET應用程序中設置ELMAH。這是很容易做到的,並且是一個非常有用的工具。

乾杯, 埃裏克

0

在ASP.NET中,程序拋出未處理的異常將調用頁面或全局錯誤處理程序之前被包裹在一個HttpUnhandledException。您需要查看其InnerException屬性以獲取最初的異常。

一般來說,除非您添加值(例如,有關異常的上下文的其他數據),否則不應該打擾包裝和重新拋出異常。只要讓它們傳播到最終處理的任何位置(您的案例中爲Page_Error,儘管您可能會考慮在global.asax.cs中使用Application_Error,以避免在每個頁面上重複此錯誤處理代碼)。

+0

我明白這一點,但我不知道如何阻止它在到達Page_Error或Application_Error處理程序之前拋出一個'UnhandledException'。 – Eric

+0

如果你想阻止傳播錯誤,你可以調用'Server.ClearError()',但我不明白爲什麼你想這樣做你的情況。 Server.Transfer無法按預期工作? – Joe

+0

我捕捉錯誤並將其重新拋入'Default.aspx.cs'文件的全部原因是因爲需要在我的服務器文件中拋出異常,而不是在我的SqlData.cs文件中,否則'Server.GetLastError( )'將會是'null'。就ASP應用程序而言,當它出現在我的類文件中時不會引發異常。 – Eric