2009-09-17 13 views
2

Webサービスに接続していますが、戻ってくる障害メッセージはデシリアライズしていません。 makeは正しくデシリアライズします。私たちは物事のサーバー側を制御することはできません。サーバーはディスカバリーを許可しないため、エンドポイントのURLの最後に?WSDLを追加すると、WSDLではなくエラーが発生します。FaultExceptionデシリアライゼーションが失敗する原因となるSOAPエラーメッセージの複数の名前空間

[フィドラー] [1]戻ってくる障害メッセージがどのように見える示しています。私たちは最初から書いてきた私たちはコードを含む(しようとXsd.exeでは、svcutilなどを作った

<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:eGov="http://eGov.gov" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <soapenv:Fault> 
    <faultcode>Client</faultcode> 
    <faultstring/> 
     <detail> 
     <eGov:eGov2Exception> 
      <eGov:ErrorClassification>SOME_ERROR</eGov:ErrorClassification> 
      <eGov:ErrorCode>SOME_ERROR_CODE</eGov:ErrorCode> 
      <eGov:ErrorMessage>Your request was unsuccessful. blah blah blah.</eGov:ErrorMessage> 
     </eGov:eGov2Exception> 
     </detail> 
    </soapenv:Fault> 
    </soapenv:Body> 
</soapenv:Envelope> 

まだクラス我々がそれをキャッチしようとすると)、それをデシリアライズすることができます

catch (FaultException<eGov2ExceptionType> exp) 
    { 
    // Never stops here. 
    } 
catch (FaultException<AllOtherAttemptedClasses> exp) 
    { 
    // Never stops here. 
    } 
catch (SoapException se) 
    { 
    // Never stops here. 
    } 
catch (FaultException exp) 
    { 
    //Always gets caught here. 
    } 

のみベースFa​​ultExceptionキャッチは、私たちがFaultMessageの内容が送信されて失うことを意味し、呼び出されます。私が書いたクラスの中には、上記のサンプルに本当に密接に連動するものがありますが、逆シリアル化に失敗するので、ネームスペースの問題があるとの疑いがあります。

質問:

1 - これはどのように書きますか?

2 - これはWCFで一般的なエラー/問題ですか?

[1]:シリアル化が完全に失敗している場合にこれを処理するhttp://www.fiddler2.com/fiddler2/フィドラー

+0

可能性のあるものhttp://stackoverflow.com/questions/4140030/c-sharp-wcf-catch-fault-exceptions-of-base-type http:// stackoverflow。com/questions/9463802/wcf-custom-fault-exception-not-caught-in-client – Ruskin

答えて

4

私たちがやったことは、フォールトを捕まえて、それをSOAPチャネルに戻すことをあきらめることでした。代わりにカスタム例外を作成し、MessageInspectorをフォルトを監視し、例外としてスローします。

(墨塗り)コードの関連部分:

public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     if (reply.IsFault) 
     { 
      XmlDictionaryReader xdr = reply.GetReaderAtBodyContents(); 
      XNode xn = XDocument.ReadFrom(xdr); 
      string s = xn.ToString(); 
      XDocument xd = XDocument.Parse(s); 
      XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/"; 
      XNamespace ns = "http://eGov.gov"; 
      XElement xErrorClass = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorClassification"); 
      XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorCode"); 
      XElement xErrorMessage = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorMessage"); 

      throw new eGovException(xErrorClass.Value, xErrorCode.Value, xErrorMessage.Value); 
     } 
    } 

メインアプリケーションは、次に使用する:

キャッチ(eGovExceptionのEX)
{
//ここに例外を処理します。
}

名前空間を修正しようとして無駄に時間が掛かっていました。回答ありがとうございます。

1

一つの方法は、入力および出力としてMessageタイプを使用してOoperationContractを使用することです。これにより、Iffault == trueのときにXMLを手動で解析したり、エラーが発生しなかった場合にGetBody()を使用して正規の内容を取得することができます。

1

まず、このWebサービスを制作した人からWSDLを取得できない場合、SOAPベースのWebサービスを持つビジネスはありません。 「?WSDL」が使用されているかどうかに関係なく、適切なWSDLが問題を解決します。

第2に、eGov2ExceptionTypeクラスのコードを掲載してください。私はそれにhttp://eGov.gov名前空間が設定されていないと思う。

+0

WSDLは、私たちの "有資格パートナー"に郵送されました。月曜日に、私が作った最も近いクラスのコードを投稿します。 – Tangurena

+0

WSDLがあれば、それをsvcutil.exeに提供して必要なものを手に入れることができます。それを試して、svcutilがエラーまたは警告メッセージを生成するかどうかを確認してください。何も表示されない場合は、生成されたクラスを調べます。生成されたコードには警告がコメントとして表示されることがあります。 –

関連する問題