更新:2007 年 11 月
當 UpdatePanel 控制項中的網頁局部更新期間發生錯誤時,預設行為是出現瀏覽器訊息對話方塊以顯示錯誤訊息。本教學課程顯示如何顯示向使用者自訂錯誤,以及如何自訂錯誤訊息。
必要條件
若要在自己的開發環境中實作這些程序,您需要:
Microsoft Visual Studio 2005 或 Microsoft Visual Web Developer Express 版。
具備 AJAX 能力的 ASP.NET 網站。
在伺服端程式碼中自訂錯誤處理
一開始,您需要在頁面中使用伺服端程式碼來自訂錯誤處理。
在伺服端程式碼中自訂錯誤處理
建立新頁面並切換至 [設計] 檢視。
在工具箱的 [AJAX 擴充功能] 索引標籤中,按兩下 ScriptManager 控制項和 UpdatePanel 控制項,將它們加入至頁面。
.png)
將下列控制項加入至 UpdatePanel 控制項內部:
兩個 TextBox 控制項。
Label 控制項
Button 控制項。將其 Text 屬性設定為計算。
UpdatePanel 控制項內的部分文字。
.png)
按兩下 [計算] 按鈕,並加入其事件處理常式的下列程式碼:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Subprotected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } }程式碼包含一個 try-catch 陳述式。在 try 區塊中,程式碼會對文字方塊中所輸入的值執行除法運算。如果作業失敗,catch 區塊中的程式碼便會將 ExtraInfo 中的額外字串資訊加入至例外狀況,然後再次擲回例外狀況而不予處理。
切換至 [設計] 檢視,然後選取 ScriptManager 控制項。
按一下 [屬性] 視窗工具列中的 [事件] 按鈕,然後按兩下 [AsyncPostBackError] 方塊以建立該事件的處理常式。
.png)
將下列程式碼加入至 AsyncPostBackError 事件處理常式:
Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Subprotected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } }程式碼會檢查是否已為例外狀況定義了 ExtraInfo 資料項目。若已定義,AsyncPostBackErrorMessage 屬性就會設定為字串值,否則會建立預設的錯誤訊息。
儲存變更,然後按 CTRL+F5 在瀏覽器中檢視頁面。
將大於零的數字加入至每個文字方塊,然後按一下 [計算] 按鈕以示範成功的回傳。
將第二個文字方塊的值變更為 0,然後按一下 [計算] 按鈕以建立錯誤條件。
瀏覽器隨即顯示一個訊息方塊,其中包含在伺服端程式碼中設定的訊息。
.png)
注意事項:訊息方塊的樣式視您所用的瀏覽器而有所不同,但在所有瀏覽器中顯示的訊息都相同。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Sub Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Partial-Page Update Error Handling Example</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html><%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } } protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Partial-Page Update Error Handling Example</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
使用用戶端指令碼自訂錯誤處理
上一個程序示範如何設定 ScriptManager 控制項的屬性,自訂網頁局部呈現期間的錯誤。下列程序則是使用用戶端 PageRequestManager 類別為自訂基礎,在 <div> 項目而非瀏覽器訊息方塊中顯示錯誤訊息。
在用戶端指令碼中自訂錯誤處理
在您稍早建立的頁面中,切換至 [原始碼] 檢視。
將下列標記加入至頁面:
<div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div><div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div>標記中包含您可用來顯示網頁局部呈現錯誤的項目。它定義了名為 AlertDiv 的 <div> 項目,該項目包含其他兩個 <div> 項目。其中一個巢狀 <div> 項目包含一個 <input> 控制項,該控制項可讓使用者隱藏 <div> 項目。
將下列樣式標記加入 <head> 項目中:
<style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style><style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style>樣式可讓錯誤資訊有別於其餘頁面內容,能夠一目了然。
切換至 [設計] 檢視,確保您的頁面結構如下:
.png)
在 [屬性] 視窗頂部的下拉式清單中,選取 DOCUMENT 項目 (代表頁面上的 <body> 項目),然後將其 Id 屬性設定為 bodytag。
.png)
切換至原始碼檢視。
將下列 <script> 區塊加入至 <asp:ScriptManager> 項目之後的任何位置。
<script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script><script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script>這個指令碼會執行下列工作:
定義 PageRequestManager 類別之 endRequest 事件的處理常式。在處理常式中,如果出現錯誤條件,程式碼就會顯示 [AlertDiv ]<div> 項目。
定義 ToggleAlertDiv 函式以隱藏或顯示 [AlertDiv] 項目,並根據錯誤狀況變更頁面色彩。
定義 ClearErrorState 函式,以隱藏錯誤訊息 UI。
儲存變更,然後按 CTRL+F5 在瀏覽器中檢視頁面。
將大於零的數字加入至每個文字方塊,然後按一下 [計算] 按鈕以示範成功的回傳。
將第二個文字方塊的值變更為 0,然後按一下 [計算] 按鈕以示範錯誤條件。
自訂的 [AlertDiv] 項目隨即顯示,而非瀏覽器訊息方塊。下圖顯示錯誤條件的範例。
.png)
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try Dim a As Int32 a = Int32.Parse(TextBox1.Text) Dim b As Int32 b = Int32.Parse(TextBox2.Text) Dim res As Int32 = a / b Label1.Text = res.ToString() Catch ex As Exception If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then ex.Data("ExtraInfo") = " You can't divide " & _ TextBox1.Text & " by " & TextBox2.Text & "." End If Throw ex End Try End Sub Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) If (e.Exception.Data("ExtraInfo") <> Nothing) Then ScriptManager1.AsyncPostBackErrorMessage = _ e.Exception.Message & _ e.Exception.Data("ExtraInfo").ToString() Else ScriptManager1.AsyncPostBackErrorMessage = _ "An unspecified error occurred." End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>UpdatePanel Error Handling Example</title> <style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style> </head> <body id="bodytag"> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div> </form> </body> </html><%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { try { int a = Int32.Parse(TextBox1.Text); int b = Int32.Parse(TextBox2.Text); int res = a / b; Label1.Text = res.ToString(); } catch (Exception ex) { if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0) { ex.Data["ExtraInfo"] = " You can't divide " + TextBox1.Text + " by " + TextBox2.Text + "."; } throw ex; } } protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { if (e.Exception.Data["ExtraInfo"] != null) { ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message + e.Exception.Data["ExtraInfo"].ToString(); } else { ScriptManager1.AsyncPostBackErrorMessage = "An unspecified error occurred."; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>UpdatePanel Error Handling Example</title> <style type="text/css"> #UpdatePanel1 { width: 200px; height: 50px; border: solid 1px gray; } #AlertDiv{ left: 40%; top: 40%; position: absolute; width: 200px; padding: 12px; border: #000000 1px solid; background-color: white; text-align: left; visibility: hidden; z-index: 99; } #AlertButtons{ position: absolute; right: 5%; bottom: 5%; } </style> </head> <body id="bodytag"> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var bodyTag = 'bodytag'; Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function ToggleAlertDiv(visString) { if (visString == 'hidden') { $get(bodyTag).style.backgroundColor = 'white'; } else { $get(bodyTag).style.backgroundColor = 'gray'; } var adiv = $get(divElem); adiv.style.visibility = visString; } function ClearErrorState() { $get(messageElem).innerHTML = ''; ToggleAlertDiv('hidden'); } function EndRequestHandler(sender, args) { if (args.get_error() != undefined) { var errorMessage; if (args.get_response().get_statusCode() == '200') { errorMessage = args.get_error().message; } else { // Error occurred somewhere other than the server page. errorMessage = 'An unspecified error occurred. '; } args.set_errorHandled(true); ToggleAlertDiv('visible'); $get(messageElem).innerHTML = errorMessage; } } </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:TextBox ID="TextBox1" Width="39px"></asp:TextBox> / <asp:TextBox ID="TextBox2" Width="39px"></asp:TextBox> = <asp:Label ID="Label1" ></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="calculate" /> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv"> <div id="AlertMessage"> </div> <br /> <div id="AlertButtons"> <input id="OKButton" type="button" value="OK" onclick="ClearErrorState()" /> </div> </div> </div> </form> </body> </html>
檢閱
本教學課程顯示數種方法,供您在網頁局部呈現期間擴充錯誤處理。在伺服端程式碼中,您可以藉由設定 AsyncPostBackErrorMessage 屬性及處理 ScriptManager 控制項的 AsyncPostBackError 事件自訂錯誤處理。在用戶端程式碼中,您則可藉由處理 PageRequestManager 類別的 endRequest 事件自訂錯誤處理。