2017-12-05 2 views
0

Ich versuche, einen SOAP-Service mit Visual Studio "Add Service Reference" Tool zu verbrauchen.Wie überschreiben Sie einen ungültigen XSD-Eigenschaftstyp in einer SOAP-Antwort, um das Parsen zu ermöglichen?

Einer der Typen in den Dienst WSDL definiert hat folgende Eigenschaft:

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

Wenn jedoch Daten, für die diese Eigenschaft Wert null anfordert, wird es in der rohen XML zurückgegeben werden, wie:

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

Welche die folgende Ausnahme verursacht, wenn die XML deserialisiert wird: FormatException: The string '' is not a valid AllXsd value.

ich nicht den Fehler in dem SOAP-Dienst zu cha beheben nge die XML-Antwort (die sollte xsd:nil als Typ haben, wenn ich richtig bin).

Was wäre eine gute Problemumgehung, so dass es keine Ausnahme auslöst und mir erlaubt, auf den Eigenschaftswert zuzugreifen, zumindest als String?

Gibt es eine Möglichkeit, die Deserialisierung der XML-Antwort zu überschreiben? Das Ändern des entsprechenden Eigenschaftstyps von DateTime zu string in der Reference.cs Datei wird nicht helfen (es scheint, dass der Deserializer die Typinformation verwendet, die in der XML-Antwort vorhanden ist).

Wenn ich die Eigenschaft von Reference.cs entfernen, wird die Ausnahme nicht ausgelöst, aber dann habe ich keinen Zugriff auf den Eigenschaftswert, den ich brauche.

+0

_ „Ändern des entsprechenden Objekttyp von Datetime-Zeichenfolge in der Datei Reference.cs wird nicht helfen,“ _ - abgesehen von den Schwierigkeiten dadurch entstehen, wenn die Proxy-Regenerieren, sollte es funktionieren. Was passiert genau, wenn Sie das tun, neu kompilieren und den Dienst anrufen? – CodeCaster

+0

@CodeCaster Ich bekomme genau die selbe Ausnahme: /, deshalb habe ich erwähnt, dass es nicht geholfen hat. Nur wenn ich die Eigenschaft lösche, verschwindet die Ausnahme (zusammen mit dem Eigenschaftswert ...) –

+0

Haben Sie versucht, Ihre lokale Kopie der WSDL zu modifizieren? – ThomasRS

Antwort

0

Ich war in der Lage, die folgende Problemumgehung zu erstellen, um die unbearbeitete XML-Antwort zu untersuchen und zu ändern, bevor sie von WCF analysiert wird.

Es ersetzt im Grunde die falsche <paymentDate xsi:type="xsd:dateTime"></paymentDate> mit der erwarteten <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; 
    } 
} 
Verwandte Themen