SOAP 錯誤訊息結構
未來的 Microsoft SQL Server 版本將移除這項功能。請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。
對 SOAP 要求的回應可以採用兩種形式之一:成功回應或錯誤回應。對於錯誤回應,回應有可能包含 HTTP 錯誤或 SOAP 錯誤。成功回應永遠都是 SOAP 訊息。如需詳細資訊,請參閱<SOAP 回應訊息結構>。
至於 HTTP 錯誤,可能的錯誤可能包含下列 HTTP 錯誤碼:「400 錯誤的要求 (例如,無效的標頭格式)」。
然而,當要求已在 HTTP 通訊層成功時,SOAP 語言管道就會處理它。這並不會產生 HTTP 層級的錯誤回應。在語言管道開始處理要求後,它會產生的唯一錯誤是 SOAP 錯誤。
當產生 SOAP 錯誤時,會傳回 HTTP 500 錯誤。在剖析要求所包含的 SOAP 封套時,於下列狀況下會產生錯誤。
SOAP 封套是無效的,例如剖析錯誤、遺漏項目等等。
在剖析期間記憶體不足的狀況。
SQL Server 登入失敗。
不支援的 SOAP 作業,例如找不到預存程序或指定未知的作業。
在要求中預存程序或使用者定義函數所傳遞和轉換的其他錯誤,例如,指定的參數數目是無效的。
在 SOAP 錯誤回應的結構中,<faultcode> 與 <detail> 項目提供錯誤的相關特定其他資訊。<faultcode> 元素與 SOAP 1.1 和 SOAP 1.2 錯誤碼規格一致。不過,<detail> 元素包含 SOAP 規格之外的修改。它在 SOAP 1.1 錯誤的 <detail> 節點中,內嵌完整的 SOAP 1.2 錯誤結構,以提供 SOAP 錯誤的相同詳細資訊給 SOAP 1.2 和 SOAP 1.1 用戶端。
所有的 SOAP 錯誤都屬於下列四個例子的其中之一:
提供詳細的 SOAP 錯誤碼資訊,但不提供 SQL Server 錯誤訊息。
當此行為發生時,SOAP 結果會對應至適當的 SOAP 錯誤。
提供詳細的 SOAP 錯誤碼,並在詳細資料節點中提供更加詳盡的 SQL Server 錯誤訊息。
會明確地處理一些 SQL Server 錯誤訊息,並將它對應至適當的 SOAP 錯誤。
傳回「未知的 SQL 錯誤」SOAP 錯誤碼,並在 <detail> 節點中提供更詳細的 SQL Server 錯誤訊息。
當此行為發生時,會在程式碼的某處引發 SQL 錯誤,但是對於特定 SOAP 錯誤將不會有特別的對應。
傳回「未知的 SQL 錯誤」SOAP 錯誤碼,但是沒有 SQL Server 錯誤訊息。
當此行為發生時,就會在某處傳回未知的結果,並對應至「未知的 SQL 錯誤」SOAP 錯誤。
範例 SOAP 1.1 錯誤
<SOAP-ENV:Fault xmlns:sqlsoapfaultcode="https://schemas.microsoft.com/sqlserver/2004/SOAP/SqlSoapFaultCode">
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>There was an error in the incoming SOAP request packet: Client, InvalidXml</faultstring>
<faultactor>https://schemas.microsoft.com/sqlserver/2004/SOAP</faultactor>
<detail xmlns:SOAP-1_2-ENV="http://www.w3.org/2003/05/soap-envelope">
<SOAP-1_2-ENV:Code>
<SOAP-1_2-ENV:Value>SOAP-1_2-ENV:Sender</SOAP-1_2-ENV:Value>
<SOAP-1_2-ENV:Subcode>
<SOAP-1_2-ENV:Value>sqlsoapfaultcode:InvalidXml</SOAP-1_2-ENV:Value>
</SOAP-1_2-ENV:Subcode>
</SOAP-1_2-ENV:Code>
<SOAP-1_2-ENV:Reason>
<SOAP-1_2-ENV:Text xml:lang="en-US">There was an error in the incoming SOAP request packet: Sender, InvalidXml</SOAP-1_2-ENV:Text>
</SOAP-1_2-ENV:Reason>
<SOAP-1_2-ENV:Node>http://MyServer:80/sql</SOAP-1_2-ENV:Node>
<SOAP-1_2-ENV:Role>https://schemas.microsoft.com/sqlserver/2004/SOAP</SOAP-1_2-ENV:Role>
<SOAP-1_2-ENV:Detail>
<sqlresultstream:SqlMessage xsi:type="sqlmessage:SqlMessage">
<sqlmessage:Class>16</sqlmessage:Class>
<sqlmessage:LineNumber>0</sqlmessage:LineNumber>
<sqlmessage:Message>XML parsing: line 3, character 0, incorrect document syntax</sqlmessage:Message>
<sqlmessage:Number>9422</sqlmessage:Number>
<sqlmessage:Source>Microsoft-SQL/9.0</sqlmessage:Source>
<sqlmessage:State>1</sqlmessage:State>
</sqlresultstream:SqlMessage>
</SOAP-1_2-ENV:Detail>
</detail>
</SOAP-ENV:Fault>
範例 SOAP 1.2 錯誤
SOAP-1_2-ENV:Fault xmlns:sqlsoapfaultcode="https://schemas.microsoft.com/sqlserver/2004/SOAP/SqlSoapFaultCode">
<SOAP-1_2-ENV:Code>
<SOAP-1_2-ENV:Value>SOAP-1_2-ENV:Sender</SOAP-1_2-ENV:Value>
<SOAP-1_2-ENV:Subcode>
<SOAP-1_2-ENV:Value>sqlsoapfaultcode:InvalidXml</SOAP-1_2-ENV:Value>
</SOAP-1_2-ENV:Subcode>
</SOAP-1_2-ENV:Code>
<SOAP-1_2-ENV:Reason>
<SOAP-1_2-ENV:Text xml:lang="en-US">There was an error in the incoming SOAP request packet: Sender, InvalidXml</SOAP-1_2-ENV:Text>
</SOAP-1_2-ENV:Reason>
<SOAP-1_2-ENV:Node>http://MyServer:80/sql</SOAP-1_2-ENV:Node>
<SOAP-1_2-ENV:Role>https://schemas.microsoft.com/sqlserver/2004/SOAP</SOAP-1_2-ENV:Role>
<SOAP-1_2-ENV:Detail>
<sqlresultstream:SqlMessage xsi:type="sqlmessage:SqlMessage">
<sqlmessage:Class>16</sqlmessage:Class>
<sqlmessage:LineNumber>0</sqlmessage:LineNumber>
<sqlmessage:Message>XML parsing: line 3, character 0, incorrect document syntax</sqlmessage:Message>
<sqlmessage:Number>9422</sqlmessage:Number>
<sqlmessage:Source>Microsoft-SQL/9.0</sqlmessage:Source>
<sqlmessage:State>1</sqlmessage:State>
</sqlresultstream:SqlMessage>
</SOAP-1_2-ENV:Detail>
</SOAP-1_2-ENV:Fault>
範例
依預設,SQL Server 會準備 SOAP 1.2 錯誤資訊。這包含 SOAP 1.1 錯誤格式不支援的其他錯誤資訊。因此,有些其他的 SOAP 1.2 相關錯誤詳細資料會以溢位方式內嵌在 SOAP 1.1 <Details> 節點中,這些資料將可由 SOAP 1.1 用戶端應用程式來剖析和擷取。
下列範例程式碼行示範一個可能的方法,以剖析 SQL Server 所傳回的 SOAP 1.1 錯誤中的 SOAP 1.2 錯誤資訊。如它所代表,此程式碼是用以做為 C# 主控台應用程式的一部分。
將剖析和擷取 SOAP 1.2 錯誤詳細資料整合至以 C# 撰寫的 SOAP 1.1 應用程式
請將下列程式碼區塊複製到 C# 主控台應用程式中的現有函數,該應用程式是用以做為 SOAP 1.1 版的用戶端。
try { ... } catch (System.Web.Services.Protocols.SoapException soapE) { // SOAP 1.1 Fault info Console.WriteLine("SOAP 1.1 fault..."); Console.WriteLine("Code: " + soapE.Code.ToString()); Console.WriteLine("Actor: " + soapE.Actor); Console.WriteLine("Detail: " + soapE.Detail.InnerXml); // Extract SOAP 1.2 Fault info from the Details node System.Xml.XmlNode fault12 = soapE.Detail; // Setup the namespace manager to use with XPath query System.Xml.NameTable nsTbl = new System.Xml.NameTable(); System.Xml.XmlNamespaceManager nsMgr = new System.Xml.XmlNamespaceManager(nsTbl); nsMgr.AddNamespace("SOAP-1_2-ENV", "http://www.w3.org/2003/05/soap-envelope"); Console.WriteLine("\r\nSOAP 1.2 fault..."); // Fault Code // Using SelectNodes() method because SOAP 1.2 fault code are allowed to have sub-codes, // this way all the fault codes are retrieved at the same time. System.Xml.XmlNodeList myNodes = fault12.SelectNodes(".//SOAP-1_2-ENV:Value", nsMgr); foreach (System.Xml.XmlNode n in myNodes) { Console.WriteLine(n.ParentNode.LocalName + ": " + n.InnerText); } // Fault Reason // SOAP 1.2 fault reason can be in multiple languages which represented as sibling "Text" child // nodes under the "Reason" node myNodes = fault12.SelectNodes(".//SOAP-1_2-ENV:Reason/SOAP-1_2-ENV:Text", nsMgr); foreach (System.Xml.XmlNode n in myNodes) { Console.WriteLine(n.ParentNode.LocalName + ": " + n.InnerText); } // Fault Node System.Xml.XmlNode faulNode = fault12.SelectSingleNode(".//SOAP-1_2-ENV:Node", nsMgr); Console.WriteLine(faulNode.LocalName + ": " + faulNode.InnerText); // Fault Role faulNode = fault12.SelectSingleNode(".//SOAP-1_2-ENV:Role", nsMgr); Console.WriteLine(faulNode.LocalName + ": " + faulNode.InnerText); }
將用以傳送 SOAP 1.1 要求訊息至 SQL Server 的程式碼取代 try { ... } 區塊中的內容。如果您一定要這麼做,您也可以將您應用程式中適用於例外狀況處理的呼叫,用來取代 Console.WriteLine() 方法呼叫。