顯示自訂的錯誤頁面 (C#)
當使用者在 ASP.NET Web 應用程式中發生執行階段錯誤時,會看到什麼? 答案取決於網站的 < customErrors > 設定方式。 根據預設,使用者會顯示不明顯黃色的螢幕,指出發生執行階段錯誤。 本教學課程示範如何自訂這些設定,以顯示符合網站外觀和風格的美觀自訂錯誤頁面。
簡介
在完美的世界中,不會發生執行階段錯誤。 程式設計人員會使用朗讀錯誤撰寫程式碼,並具有健全的使用者輸入驗證,而資料庫伺服器和電子郵件伺服器等外部資源永遠不會離線。 當然,事實上,錯誤是不可避免的。 .NET Framework中的類別會擲回例外狀況來發出錯誤訊號。 例如,呼叫 SqlConnection 物件的 Open 方法會建立與連接字串所指定之資料庫的連線。 不過,如果資料庫已關閉或連接字串中的認證無效,則 Open 方法會擲回 SqlException
。 使用 區塊可以處理 try/catch/finally
例外狀況。 如果區塊內的 try
程式碼擲回例外狀況,控制項會傳送至適當的 catch 區塊,讓開發人員可以嘗試從錯誤中復原。 如果沒有相符的 catch 區塊,或擲回例外狀況的程式碼不在 try 區塊中,例外狀況就會在搜尋 try/catch/finally
區塊時將呼叫堆疊編碼。
如果例外狀況會一直升至 ASP.NET 執行時間,而不需處理,HttpApplication
就會引發 類別Error
的事件,並顯示已設定的錯誤頁面。 根據預設,ASP.NET 會顯示一個受影響的錯誤頁面,稱為「 黃色 死 (畫面 YSOD) 」 。 YSOD 有兩個版本:一個顯示例外狀況詳細資料、堆疊追蹤,以及其他有助於開發人員偵錯應用程式的資訊, (請參閱 圖 1) ;另一個只是指出執行階段錯誤 (請參閱 圖 2) 。
例外狀況詳細資料 YSOD 對於開發人員偵錯應用程式相當有説明,但向使用者顯示 YSOD 是 tacky 和 unprofessional。 相反地,使用者應該會前往錯誤頁面,以維護網站的外觀和風格,以更方便使用者方式描述這種情況。 好消息是建立這類自訂錯誤頁面相當容易。 本教學課程從 ASP 開始。NET 的不同錯誤頁面。 接著會示範如何設定 Web 應用程式,以在發生錯誤時向使用者顯示自訂錯誤頁面。
檢查三種類型的錯誤頁面
當發生未處理的例外狀況時,ASP.NET 應用程式會顯示三種錯誤頁面的其中一種:
- [例外狀況詳細資料] 黃色的 [死死畫面] 頁面,
- [執行時間錯誤黃色畫面的死死錯誤] 頁面,或
- 自訂錯誤頁面
錯誤頁面開發人員最熟悉的是例外狀況詳細資料 YSOD。 根據預設,此頁面會顯示給在本機流覽的使用者,因此是您在開發環境中測試網站時看到錯誤時看到的頁面。 如同其名稱,例外狀況詳細資料 YSOD 提供例外狀況的詳細資料 - 類型、訊息和堆疊追蹤。 此外,如果例外狀況是由您 ASP.NET 網頁程式碼後置類別中的程式碼所引發,而且應用程式已設定偵錯,則例外狀況詳細資料 YSOD 也會顯示這行程式碼 (,以及上方和下方幾行程式碼) 。
圖 1 顯示例外狀況詳細資料 YSOD 頁面。 請注意瀏覽器位址視窗中的 URL: http://localhost:62275/Genre.aspx?ID=foo
。 回想一下, Genre.aspx
頁面會列出特定內容類型中的書籍評論。 它要求 GenreId
(uniqueidentifier
透過查詢字串傳遞) 值;例如,檢視虛構評論的適當 URL 是 Genre.aspx?ID=7683ab5d-4589-4f03-a139-1c26044d0146
。 如果透過 querystring (傳入非 uniqueidentifier
值,例如 「foo」) 擲回例外狀況。
注意
若要在可供下載的示範 Web 應用程式中重現此錯誤,您可以直接流覽 Genre.aspx?ID=foo
,或按一下 中的 Default.aspx
[產生執行時間錯誤] 連結。
請注意 圖 1中顯示的例外狀況資訊。 例外狀況訊息「從字元字串轉換成 uniqueidentifier 時,轉換失敗」會出現在頁面頂端。 例外 System.Data.SqlClient.SqlException
狀況的類型也會列出。 還有堆疊追蹤。
圖 1:例外狀況詳細資料 YSOD 包含例外狀況的相關資訊
(按一下即可檢視完整大小的映射)
其他類型的 YSOD 是執行時間錯誤 YSOD, 如圖 2所示。 執行時間錯誤 YSOD 會通知訪客發生執行階段錯誤,但不包含擲回之例外狀況的任何資訊。 不過, (它確實會提供如何藉由修改 Web.config
檔案來檢視錯誤詳細資料的指示,這是讓這類 YSOD 看起來不是professional.)
根據預設,執行時間錯誤 YSOD 會顯示給從遠端流覽的使用者, (透過 http://www.yoursite.com) ,如圖 2的瀏覽器網址列中的 URL 辨識: http://httpruntime.web703.discountasp.net/Genre.aspx?ID=foo
。 有兩個不同的 YSOD 畫面存在,因為開發人員有興趣瞭解錯誤詳細資料,但這類資訊不應該顯示在即時網站上,因為它可能會向使用者流覽您的網站的人顯示潛在的安全性弱點或其他敏感性資訊。
注意
如果您跟著使用 DiscountASP.NET 做為 Web 主機,您可能會注意到流覽即時網站時,執行時間錯誤 YSOD 不會顯示。 這是因為 DiscountASP.NET 其伺服器已設定為預設顯示例外狀況詳細資料 YSOD。 好消息是,您可以將區 <customErrors>
段新增至檔案 Web.config
,以覆寫此預設行為。 [設定顯示哪個錯誤頁面] 區段會詳細檢查區 <customErrors>
段。
圖 2:執行時間錯誤 YSOD 不包含任何錯誤詳細資料
(按一下即可檢視完整大小的映射)
第三種類型的錯誤頁面是自訂錯誤頁面,這是您所建立的網頁。 自訂錯誤頁面的優點是,您可以完全控制向使用者顯示的資訊,以及頁面的外觀和風格;自訂錯誤頁面可以使用與您其他頁面相同的主版頁面和樣式。 [使用自訂錯誤頁面] 區段會逐步解說如何建立自訂錯誤頁面,並將它設定為在未處理的例外狀況發生時顯示。 圖 3 提供這個自訂錯誤頁面的先行尖峰。 如您所見,錯誤頁面的外觀和風格比圖 1 和 2 所示的其中一個黃色畫面更專業。
圖 3:自訂錯誤頁面提供更量身打造的外觀和風格
(按一下即可檢視完整大小的映射)
花點時間檢查 圖 3中的瀏覽器網址列。 請注意,網址列會顯示自訂錯誤頁面的 URL (/ErrorPages/Oops.aspx
) 。 在圖 1 和 2 中,黃色的死畫面會顯示在與錯誤源自 () Genre.aspx
相同的頁面中。 自訂錯誤頁面會透過 querystring 參數傳遞頁面的 URL,其中發生 aspxerrorpath
錯誤。
設定顯示哪個錯誤頁面
顯示三個可能錯誤頁面的哪一個是以兩個變數為基礎:
- 區段中的組
<customErrors>
態資訊,以及 - 使用者是在本機或遠端流覽網站。
中的 Web.config
區 <customErrors>
段有兩個會影響所顯示錯誤頁面的屬性: defaultRedirect
和 mode
。 defaultRedirect
屬性是選擇性的。 如果提供,它會指定自訂錯誤頁面的 URL,並指出應該顯示自訂錯誤頁面,而不是執行時間錯誤 YSOD。 屬性 mode
是必要屬性,且接受三個值之一: On
、 Off
或 RemoteOnly
。 這些值具有下列行為:
On
- 指出自訂錯誤頁面或執行時間錯誤 YSOD 會顯示給所有訪客,不論它們是本機還是遠端。Off
- 指定例外狀況詳細資料 YSOD 會顯示給所有訪客,不論這些訪客是本機還是遠端。RemoteOnly
- 指出自訂錯誤頁面或執行時間錯誤 YSOD 會顯示給遠端訪客,而例外狀況詳細資料 YSOD 會顯示給本機訪客。
除非您另有指定,否則 ASP.NET 如同您已將 mode 屬性設定為 RemoteOnly
,而且尚未指定 defaultRedirect
值。 換句話說,預設行為是例外狀況詳細資料 YSOD 會顯示給本機訪客,而執行時間錯誤 YSOD 會顯示給遠端訪客。 您可以將區 <customErrors>
段新增至 Web 應用程式的 來覆寫此預設行為 Web.config file.
使用自訂錯誤頁面
每個 Web 應用程式都應該有自訂錯誤頁面。 它提供更專業型式的執行時間錯誤 YSOD 替代方法,很容易建立,而且設定應用程式使用自訂錯誤頁面只需要幾分鐘的時間。 第一個步驟是建立自訂錯誤頁面。 我已將新的資料夾新增至名為 ErrorPages
的 Book Reviews 應用程式,並新增至名為 Oops.aspx
的新 ASP.NET 網頁。 讓頁面使用與網站上其餘頁面相同的主版頁面,以便自動繼承相同的外觀和風格。
圖 4:建立自訂錯誤頁面
接下來,花幾分鐘的時間建立錯誤頁面的內容。 我建立了一個相當簡單的自訂錯誤頁面,其中包含一則訊息,指出發生非預期的錯誤,以及網站首頁的連結。
圖 5:設計您的自訂錯誤頁面
(按一下即可檢視完整大小的影像)
完成錯誤頁面之後,請將 Web 應用程式設定為使用自訂錯誤頁面,而不是執行時間錯誤 YSOD。 這可藉由在 區段的 屬性中 <customErrors>
指定錯誤頁面的 defaultRedirect
URL 來完成。 將下列標記新增至應用程式的 Web.config
檔案:
<configuration>
...
<system.web>
<customErrors mode="RemoteOnly"
defaultRedirect="~/ErrorPages/Oops.aspx" />
...
</system.web>
</configuration>
上述標記會將應用程式設定為向使用者顯示本機流覽的例外狀況詳細資料 YSOD,同時針對遠端流覽的使用者使用自訂錯誤頁面 Oops.aspx。 若要查看運作情形,請將您的網站部署至生產環境,然後流覽即時網站上具有無效查詢字串值的 Genre.aspx 頁面。 您應該會看到自訂錯誤頁面 (回 圖 3) 。
若要確認自訂錯誤頁面只會向遠端使用者顯示,請流覽 Genre.aspx
來自開發環境且查詢字串不正確頁面。 您應該仍會看到例外狀況詳細資料 YSOD (請參閱 圖 1) 。 此 RemoteOnly
設定可確保在生產環境中流覽網站的使用者會看到自訂錯誤頁面,而開發人員在本機工作時仍可繼續查看例外狀況的詳細資料。
通知開發人員和記錄錯誤詳細資料
開發環境中發生的錯誤是由位於電腦中的開發人員所造成。 她會在例外狀況詳細資料 YSOD 中顯示例外狀況的資訊,而且她知道發生錯誤時所執行的步驟。 但是當生產環境發生錯誤時,除非使用者流覽網站需要一段時間來報告錯誤,否則開發人員不知道發生錯誤。 即使使用者沒有辦法通知開發小組發生錯誤,但不知道例外狀況類型、訊息和堆疊追蹤,可能很難診斷錯誤的原因,而單獨加以修正。
基於這些原因,生產環境中的任何錯誤都會記錄到某些持續性存放區 (,例如資料庫) ,而且開發人員收到此錯誤的警示。 自訂錯誤頁面似乎適合用來執行此記錄和通知。 不幸的是,自訂錯誤頁面無法存取錯誤詳細資料,因此無法用來記錄這項資訊。 好消息是有數種方式可以攔截錯誤詳細資料並加以記錄,接下來三個教學課程會更詳細地探索本主題。
針對不同的 HTTP 錯誤狀態使用不同的自訂錯誤頁面
當 ASP.NET 網頁擲回例外狀況且未處理時,例外狀況會依 ASP.NET 執行時間而增加,以顯示設定的錯誤頁面。 如果要求進入 ASP.NET 引擎,但因為某些原因而無法處理 - 可能找不到要求的檔案或已停用檔案的讀取權限 - 則 ASP.NET 引擎會 HttpException
引發 。 此例外狀況與從 ASP.NET 網頁引發的例外狀況一樣,會反升至執行時間,導致顯示適當的錯誤頁面。
這代表在生產環境中 Web 應用程式的意義是,如果使用者要求找不到的頁面,他們就會看到自訂錯誤頁面。 圖 6 顯示這類範例。 由於要求適用于不存在的頁面 (NoSuchPage.aspx
) ,因此會擲回 , HttpException
並顯示自訂錯誤頁面 (請注意 querystring 參數) 中的 aspxerrorpath
參考 NoSuchPage.aspx
。
圖 6:ASP.NET 執行時間會顯示已設定的錯誤頁面,以回應不正確要求, (按一下即可檢視完整大小的影像)
根據預設,所有類型的錯誤都會顯示相同的自訂錯誤頁面。 不過,您可以使用 區段中的子專案 <customErrors>
,針對特定 HTTP 狀態碼 <error>
指定不同的自訂錯誤頁面。 例如,若要在頁面找不到錯誤時顯示不同的錯誤頁面,其 HTTP 狀態碼為 404,請更新 區 <customErrors>
段以包含下列標記:
<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/Oops.aspx">
<error statusCode="404" redirect="~/ErrorPages/404.aspx" />
</customErrors>
有了這項變更,每當使用者從遠端要求不存在 ASP.NET 資源時,都會重新導向至 404.aspx
自訂錯誤頁面,而不是 Oops.aspx
。 如圖 7 所示, 404.aspx
頁面可以包含比一般自訂錯誤頁面更明確的訊息。
注意
如需建立有效 404 錯誤頁面的指引 ,請參閱 404 錯誤頁面 。
圖 7:自訂 404 錯誤頁面顯示的目標訊息比 Oops.aspx
(按一下即可檢視完整大小的影像)
由於您知道 404.aspx
只有在使用者提出找不到頁面的要求時,才能到達頁面,因此您可以增強此自訂錯誤頁面,以包含功能來協助使用者解決這種特定類型的錯誤。 例如,您可以建置資料庫資料表,將已知的不良 URL 對應至良好的 URL,然後讓 404.aspx
自訂錯誤頁面針對該資料表執行查詢,並建議使用者可能嘗試連線的頁面。
注意
只有在對 ASP.NET 引擎處理的資源提出要求時,才會顯示自訂錯誤頁面。 如我們在 IIS 與 ASP.NET 開發伺服器教學課程的核心差異 中所討論,網頁伺服器可能會處理特定要求本身。 根據預設,IIS 網頁伺服器會處理靜態內容的要求,例如影像和 HTML 檔案,而不叫用 ASP.NET 引擎。 因此,如果使用者要求不存在的映射檔,則會傳回 IIS 的預設 404 錯誤訊息,而不是 ASP。NET 的設定錯誤頁面。
總結
在 ASP.NET 應用程式中發生未處理的例外狀況時,使用者會顯示三個錯誤頁面的其中一個:例外狀況詳細資料黃色的死訊畫面;[執行階段錯誤] 黃色的 [死死畫面] ;或自訂錯誤頁面。 顯示哪個錯誤頁面取決於應用程式的組 <customErrors>
態,以及使用者是在本機或遠端流覽。 預設行為是向本機訪客顯示例外狀況詳細資料 YSOD,以及遠端訪客的執行時間錯誤 YSOD。
雖然執行時間錯誤 YSOD 會隱藏使用者流覽網站的潛在敏感性錯誤資訊,但它會中斷網站的外觀與操作,並讓應用程式看起來很錯誤。 更好的方法是使用自訂錯誤頁面,這需要建立和設計自訂錯誤頁面,並在 區段的 defaultRedirect
屬性中 <customErrors>
指定其 URL。 您甚至可以針對不同的 HTTP 錯誤狀態有多個自訂錯誤頁面。
自訂錯誤頁面是生產環境中網站的完整錯誤處理策略中的第一個步驟。 警示開發人員錯誤並記錄其詳細資料也是重要的步驟。 接下來三個教學課程會探索錯誤通知和記錄的技術。
快樂的程式設計!
深入閱讀
如需本教學課程中所討論之主題的詳細資訊,請參閱下列資源: