SOAP エラー メッセージの構造

この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。

SOAP 要求への応答は、成功を示す応答またはエラー応答の 2 つの形式のいずれかになります。エラー応答の場合、応答には HTTP エラーまたは SOAP エラーが含まれます。成功を示す応答は、常に SOAP メッセージです。詳細については、「SOAP 応答メッセージの構造」を参照してください。

HTTP エラーでは、エラーには "400 正しくない要求" (たとえば、無効なヘッダー形式) など、HTTP エラー コードが含まれることが考えられます。

ただし、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.2 および SOAP 1.1 クライアントの両方に SOAP エラーに関する同じ詳細情報が提供されます。この処理は、完全な SOAP 1.2 エラー構造を SOAP 1.1 エラーの <detail> ノードに埋め込むことによって行います。

すべての SOAP エラーは、次の 4 つのいずれかのように発生します。

  • 詳細な SOAP エラー コード情報は提供されるが、SQL Server エラー メッセージが提供されない。

    この現象が発生した場合、SOAP の結果は適切な SOAP エラーにマップされます。

  • 詳細な SOAP エラー コードが提供され、より詳細な SQL Server エラー メッセージが detail ノードに表示される。

    SQL Server エラー メッセージの一部が、明示的に処理され、適切な SOAP エラーにマップされます。

  • "不明な SQL エラー" SOAP エラー コードが返され、より詳細な SQL Server エラー メッセージが <detail> ノードに表示される。

    この現象が発生した場合、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> ノードに埋め込まれます。<Details> ノードは、SOAP 1.1 クライアント アプリケーションによってエラーを解析および取得できます。

次のサンプル コードでは、SQL Server によって返される、SOAP 1.1 エラーからの SOAP 1.2 エラー情報を解析する方法として考えられる例を 1 つ示しています。現時点では、このコードは、C# コンソール アプリケーションの一部として使用することを目的としています。

SOAP 1.2 エラーの詳細を解析および取得する処理を、C# で記述された SOAP 1.1 アプリケーションに統合するには

  1. SOAP 1.1 バージョンのクライアントとして機能するように使用されている、C# コンソール アプリケーション内の既存の関数に、次のコード ブロックをコピーします。

    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() メソッドの呼び出しを、アプリケーションの例外処理に適したメソッドの呼び出しに置き換えることができます。