在 XML Web Service 中處理和擲回例外狀況
使用 ASP.NET 建立的 XML Web Service 方法所擲回的例外狀況會以 SOAP 錯誤格式傳回用戶端。所謂 SOAP 錯誤,是 SOAP 訊息內的 <Fault> XML 項目,指出錯誤何時發生。需要傳遞 SOAP 錯誤時,ASP.NET 會按照指示方法,將錯誤以 SOAP 規格傳回用戶端。SOAP <Fault> XML 項目包含例外狀況字串和例外狀況來源等詳細資訊。如需 SOAP 錯誤的詳細資訊,請參閱 W3C 網站 (http://www.w3c.org/TR/SOAP)。
有一點相當重要,用戶端和使用 ASP.NET 建立的 XML Web Service 不會直接填入或剖析 <Fault> XML 項目,而是使用通用設計模式來擲回及攔截 .NET Framework 中的例外狀況。XML Web Service 能夠針對問題擲回例外,例如 ArgumentOutOfRangeException 或 SoapException。無論是哪種方式,ASP.NET 都將例外放入 SOAP 錯誤項目,將例外序列化至有效的 SOAP 訊息中。SOAP 訊息在 ASP.NET 用戶端經過序列化還原後,SOAP 錯誤會轉換成 SoapException 例外狀況,其例外狀況詳細資訊放在 Message 屬性中。用戶端可接著設定 Try/Catch 區塊來攔截 SoapException。
Web 應用程式可由多重 XML Web Service 構成,但是 Global.asax 檔案中的 Application_Error 事件不可用來進行全域例外處理 (Exception Handling)。XML Web Service 的 HttpHandler 會使用 XML Web Service 執行期間發生的所有例外狀況,並在呼叫 Application_Error 事件前將例外狀況轉換為 SOAP 錯誤。請您建置 SOAP 擴充功能,以處理全域例外處理常式 (Exception Handler) 中的 XML Web Service 例外狀況。SOAP 擴充功能可以檢查 ProcessMessage 方法中是否有例外狀況。在 ProcessMessage 方法內,請檢查當 Stage 屬性設定為 AfterSerialize 時,傳遞的 SoapMessage 的 Exception 屬性。如需 SOAP 擴充功能的詳細資訊,請參閱使用 SOAP 擴充功能改變 SOAP 訊息。
從使用 ASP.NET 建立的 XML Web Service 擲回例外狀況
錯誤是以擲回例外狀況的方式傳回用戶端。XML Web Service 方法可用四種方式達到這個目的:
- 擲回 SoapException 例外狀況。
- 擲回 SoapHeaderException 例外狀況。
- 針對問題擲回例外狀況。
- 允許 ASP.NET 擲回例外狀況。
下列資料表描述 XML Web Service 能明確擲回的例外狀況,以及 ASP.NET 用戶端如何接收每個例外狀況。
擲回的例外狀況類型 | XML Web Service 的功能 |
---|---|
SoapException 和 SoapHeaderException 以外的例外狀況 | 這種 XML Web Service 方法能偵測例外狀況案例,並將 ArgumentOutOfRangeException 等特定例外狀況擲回用戶端。ASP.NET 用戶端接收 SoapException,其詳細資訊已序列化為文字放在 Message 屬性中。 |
SoapException | 這種 XML Web Service 方法能偵測例外狀況案例並擲回 SoapException,同時提供與問題相關的其他詳細資訊。這些其他資訊由 XML Web Service 方法填入 Detail 屬性。所以,ASP.NET 用戶端接收的 SoapException 包含其他資訊。 |
SoapHeaderException | XML Web Service 方法處理 SOAP 標頭時會一併偵測例外狀況案例。XML Web Service 方法必須根據 SOAP 規格,將 SoapHeaderException 擲回用戶端,這樣 ASP.NET 用戶端便會收到 SoapHeaderException。 |
若要從 XML Web Service 擲回例外狀況
針對問題擲回例外狀況,例如 SoapException 或 SoapHeaderException,如上表所述。
下列程式碼範例會擲回 SoapException,並設定 Detail 屬性來提供例外狀況的其他詳細資訊。
<%@ WebService Language="VB" class="ThrowSoapException"%> Imports System Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Xml.Serialization Imports System.Xml Public Class ThrowSoapException Inherits WebService ' This XML Web service method throws a SOAP client fault code. <WebMethod()> _ Public Sub myThrow() ' Build the detail element of the SOAP fault. Dim doc As New System.Xml.XmlDocument() Dim node As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ SoapException.DetailElementName.Name, _ SoapException.DetailElementName.Namespace) ' Build specific details for the SoapException. ' Add first child of detail XML element. Dim details As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ "mySpecialInfo1", "http://tempuri.org/") ' Add second child of detail XML element with an attribute. Dim details2 As System.Xml.XmlNode = _ doc.CreateNode(XmlNodeType.Element, _ "mySpecialInfo2", "http://tempuri.org/") Dim attr As XmlAttribute = doc.CreateAttribute("t", _ "attrName", "http://tempuri.org/") attr.Value = "attrValue" details2.Attributes.Append(attr) ' Append the two child elements to the detail node. node.AppendChild(details) node.AppendChild(details2) 'Throw the exception. Dim se As New SoapException("Fault occurred", _ SoapException.ClientFaultCode, _ Context.Request.Url.AbsoluteUri, node) Throw se Return End Sub End Class [C#] <%@ WebService Language="C#" class="ThrowSoapException"%> using System; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; using System.Xml; public class ThrowSoapException : WebService { // This XML Web service method throws a SOAP client fault code. [WebMethod] public void myThrow(){ // Build the detail element of the SOAP fault. System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); System.Xml.XmlNode node = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace); // Build specific details for the SoapException. // Add first child of detail XML element. System.Xml.XmlNode details = doc.CreateNode(XmlNodeType.Element, "mySpecialInfo1", "http://tempuri.org/"); System.Xml.XmlNode detailsChild = doc.CreateNode(XmlNodeType.Element, "childOfSpecialInfo", "http://tempuri.org/"); details.AppendChild(detailsChild); // Add second child of detail XML element with an attribute. System.Xml.XmlNode details2 = doc.CreateNode(XmlNodeType.Element, "mySpecialInfo2", "http://tempuri.org/"); XmlAttribute attr = doc.CreateAttribute("t", "attrName", "http://tempuri.org/"); attr.Value = "attrValue"; details2.Attributes.Append(attr); // Append the two child elements to the detail node. node.AppendChild(details); node.AppendChild(details2); //Throw the exception SoapException se = new SoapException("Fault occurred", SoapException.ClientFaultCode, Context.Request.Url.AbsoluteUri , node); throw se; return; } }
若要攔截 XML Web Service 方法擲回的例外狀況
在 Try/Catch 區塊間攔截 SoapException (XML Web service 方法所擲回的任何例外均為 SoapException)。
下列程式碼範例中,用戶端呼叫能擷取 XML Web Service 方法所擲回例外狀況的 XML Web Service 方法。然後,用戶端以攔截到的 SoapException 屬性填入 HTML 資料表。
<%@ Import Namespace="System.Web.Services.Protocols" %> <%@ Import Namespace="System.Xml" %> <%@ Page Language="vb" %> <html> <head> <script runat=server language=vb> Sub Page_Load(o As Object, e As EventArgs) ' Create a new instance of the XML Web service class. Dim ThrowsSoapException As ThrowSoapException = New _ ThrowSoapException() Try ThrowsSoapException.myThrow() Catch myerr As SoapException ' Populate the table with the exception details. ErrorTable.Rows.Add(BuildNewRow("Fault Code Namespace", _ myerr.Code.Namespace)) ErrorTable.Rows.Add(BuildNewRow("Fault Code Name", _ myerr.Code.Name)) ErrorTable.Rows.Add(BuildNewRow( _ "SOAP Actor that threw Exception", myerr.Actor)) ErrorTable.Rows.Add(BuildNewRow("Error Message", _ myerr.Message)) ErrorTable.Rows.Add(BuildNewRow("Detail", _ HttpUtility.HtmlEncode(myerr.Detail.OuterXml) )) Return End Try End Sub 'Page_Load Function BuildNewRow(Cell1Text As String, Cell2Text As String) _ As HtmlTableRow Dim row As New HtmlTableRow() Dim cell1 As New HtmlTableCell() Dim cell2 As New HtmlTableCell() 'Set the contents of the two cells. cell1.Controls.Add(New LiteralControl(Cell1Text)) 'Add the cells to the row. row.Cells.Add(cell1) cell2.Controls.Add(New LiteralControl(Cell2Text)) 'Add the cells to the row. row.Cells.Add(cell2) Return row End Function 'BuildNewRow </script> <head> <body> <table id="ErrorTable" CellPadding=5 CellSpacing=0 Border="1" BorderColor="black" runat="server" /> </body> [C#] <%@ Import Namespace="System.Web.Services.Protocols" %> <%@ Import Namespace="System.Xml" %> <%@ Page Language="C#" %> <html> <head> <script runat=server language=c#> void Page_Load(Object o, EventArgs e){ // Create a new instance of the XML Web service proxy class. ThrowSoapException throwSoapException = new ThrowSoapException(); // Make a call to the XML Web service method, which throws an // exception. try { throwSoapException.myThrow(); } catch (SoapException error) { // Populate the table with the exception details. ErrorTable.Rows.Add(BuildNewRow("Fault Code Namespace", error.Code.Namespace)); ErrorTable.Rows.Add(BuildNewRow("Fault Code Name", error.Code.Name)); ErrorTable.Rows.Add(BuildNewRow( "SOAP Actor that threw Exception", error.Actor)); ErrorTable.Rows.Add(BuildNewRow("Error Message", error.Message)); ErrorTable.Rows.Add(BuildNewRow("Detail", HttpUtility.HtmlEncode(error.Detail.OuterXml))); return; } } // This populates a row in an HtmlTable. HtmlTableRow BuildNewRow(string Cell1Text, string Cell2Text) { HtmlTableRow row = new HtmlTableRow(); HtmlTableCell cell1 = new HtmlTableCell(); HtmlTableCell cell2 = new HtmlTableCell(); //Set the contents of the two cells. cell1.Controls.Add(new LiteralControl(Cell1Text)); //Add a cell to the row. row.Cells.Add(cell1); cell2.Controls.Add(new LiteralControl(Cell2Text)); //Add a cell to the row. row.Cells.Add(cell2); return row; } </script> <head> <body> <table id="ErrorTable" CellPadding=5 CellSpacing=0 Border="1" BorderColor="black" runat="server" /> </body>
XML Web Service 方法未處理的例外狀況
如果 XML Web Service 方法未攔截方法中發生的例外狀況,請參閱下表中綱要列出的 ASP.NET 例外狀況處理方法。
發生未處理的例外 | ASP.NET 處理方法 |
---|---|
執行 XML Web Service 方法期間 | ASP.NET 會攔截例外狀況並擲回用戶端。使用 .NET Framework 建立的 XML Web Service 用戶端會收到 SoapException 及內含特定例外狀況的 InnerException 屬性。 |
處理 SOAP 標頭期間 | ASP.NET 會擲回 SoapHeaderException。使用 .NET Framework 建立的 XML Web Service 用戶端會收到 SoapHeaderException。 |
請參閱
SoapException 類別 | SoapHeaderException 類別 | 處理和擲回例外狀況 | 使用 ASP.NET 建置 XML Web Service | 建置 XML Web Service 用戶端