Поделиться через


Структура сообщения о сбое SOAP

В будущей версии Microsoft SQL Server эта возможность будет удалена. Избегайте использования этой возможности в новых разработках и запланируйте изменение существующих приложений, в которых она применяется.

Ответы на требования SOAP могут принимать одну из двух форм: сообщения об успехе или сообщения об ошибках. Сообщение об ошибке может содержать как ошибки HTTP, так и сбои SOAP. Сообщение об успехе — это всегда сообщение SOAP. Дополнительные сведения см. в разделе Структура сообщения-ответа SOAP.

Возможная ошибка HTTP может включать в себя следующий код: «400 Bad request (e.g. invalid header format)»

Однако после того как требование успешно обработано на уровне протокола 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 клиентам SOAP 1.2 и SOAP 1.1, встраивая полную структуру сбоя SOAP 1.2 в узел <detail> сбоя SOAP 1.1.

Все сбои SOAP принадлежат к одному из следующих четырех вариантов:

  • Предоставлены подробные сведения о коде ошибки SOAP, однако не выведены сообщения об ошибках SQL Server.

    При таком поведении результат SOAP сопоставляется с соответствующим сбоем SOAP.

  • Предоставлены подробные сведения о коде ошибки SOAP с более детальным сообщением об ошибке SQL Server в узле подробностей.

    Некоторые сообщения об ошибках SQL Server явным образом обрабатываются и сопоставлены с соответствующими сбоями SOAP.

  • Возвращен код ошибки SOAP «Неизвестная ошибка SQL», а также более подробное сообщение об ошибке SQL Server в узле <detail>.

    При таком поведении ошибка SQL была вызвана каким-либо участком кода, но не существует специального сопоставления с конкретным сбоем SOAP.

  • Возвращен код ошибки SOAP «Неизвестная ошибка SQL» без сообщения об ошибке SQL Server.

    При таком поведении неизвестный результат был возвращен где-либо и сопоставлен со сбоем SOAP «Неизвестная ошибка SQL».

Образец сбоя 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, встраиваются в качестве дополнения в узел <Details> SOAP 1.1, где они могут быть проанализированы и откуда могут быть получены клиентскими приложениями SOAP 1.1.

Нижеприведенные строчки примера кода демонстрируют один из возможных способов извлечения данных о сбое SOAP 1.2 из данных о сбое SOAP 1.1, возвращенных SQL Server. В представленном виде этот код предназначен для использования в качестве части консольного приложения C#.

Интеграция анализа и извлечения деталей сбоя SOAP 1.2 в приложение SOAP 1.1, написанное на C#

  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);}
    
  2. Замените содержимое блока try { ... } кодом, используемым для отправки запроса SOAP 1.1 к SQL Server. Если необходимо, можно также заменить вызовы метода Console.WriteLine() вызовами любого метода, пригодного для обработки исключений в приложении.