2017-12-05 4 views
0

Visual Studioの「サービス参照の追加」ツールを使用してSOAPサービスを使用しようとしています。サービスのWSDLで定義された型の解析を許可するためにSOAP応答で無効なXSDプロパティタイプをオーバーライドする方法はありますか?

一つは、次のプロパティがあります。

:このプロパティの値がnullであるためにデータを要求するときに

<xsd:element name="paymentDate" type="xsd:dateTime" /> 

はしかし、それはのように生のXMLで返されます私は茶へのSOAPサービスのバグを修正することはできませんFormatException: The string '' is not a valid AllXsd value.

:XMLをデシリアライズされ、次の例外が発生し

<paymentDate xsi:type="xsd:dateTime"/> 

XML応答(正しい場合は、xsd:nilをタイプとして使用する必要があります)を設定します。

例外がスローされず、少なくとも文字列としてプロパティ値にアクセスできるようにするには、どのような回避策を講じてください。

XMLレスポンスの逆シリアル化を無効にする方法はありますか? Reference.csファイル内の対応するプロパティタイプをDateTimeからstringに変更することは役に立ちません(デシリアライザはXML応答に存在するタイプ情報を使用しているようです)。

Reference.csからプロパティを削除した場合、例外はスローされませんが、必要なプロパティ値にアクセスできません。

+0

_ _「Reference.csファイル内の文字列へのDateTimeから対応するプロパティのタイプを変更すると、助けにはなりません」 - これは、プロキシを再生成するとき、それが動作するはず原因になりますトラブルがなければ。これを実行し、再コンパイルしてサービスを呼び出すと、正確に何が起こりますか? – CodeCaster

+0

@CodeCaster私はまったく同じ例外を受け取ります:/これが助けにならないと言いました。プロパティを削除した場合にのみ、例外が(プロパティ値と共に)消えてしまいます。 –

+0

WSDLのローカルコピーを変更しようとしましたか? – ThomasRS

答えて

0

生のXML応答を検査し、WCFによって解析される前に修正するために、次の回避策を考え出すことができました。

これは、間違った<paymentDate xsi:type="xsd:dateTime"></paymentDate>を、基本的には<paymentDate xsi:nil="true"></paymentDate>と置き換えます。

public class MyRoutine { 
    public static void Main() { 
     var client = new MyServiceClient(); 
     client.Endpoint.Behaviors.Add(new InspectorBehavior()); 
    } 
} 

public class InspectorBehavior : IEndpointBehavior { 
    public void Validate(ServiceEndpoint endpoint) { 
    } 

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { 
     clientRuntime.MessageInspectors.Add(new MyMessageInspector()); 
    } 
} 

public class MyMessageInspector : IClientMessageInspector { 
    public object BeforeSendRequest(ref Message request, IClientChannel channel) { 
     return null; 
    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) { 
     reply = ChangeString(reply, from: "<paymentDate xsi:type=\"xsd:dateTime\"></paymentDate>", to: "<paymentDate xsi:nil=\"true\"></paymentDate>"); 
    } 

    public static Message ChangeString(Message oldMessage, string from, string to) { 
     var ms = new MemoryStream(); 
     var xw = XmlWriter.Create(ms); 
     oldMessage.WriteMessage(xw); 
     xw.Flush(); 
     var body = Encoding.UTF8.GetString(ms.ToArray()); 
     xw.Close(); 

     body = body.Replace(from, to); 

     ms = new MemoryStream(Encoding.UTF8.GetBytes(body)); 
     var xdr = XmlDictionaryReader.CreateTextReader(ms, new XmlDictionaryReaderQuotas()); 
     var newMessage = Message.CreateMessage(xdr, int.MaxValue, oldMessage.Version); 
     newMessage.Properties.CopyProperties(oldMessage.Properties); 
     return newMessage; 
    } 
} 
関連する問題