【问题标题】:How to override an invalid XSD property type in a SOAP response to allow parsing?如何覆盖 SOAP 响应中的无效 XSD 属性类型以允许解析?
【发布时间】:2017-12-05 10:04:44
【问题描述】:

我正在尝试使用 Visual Studio 的“添加服务引用”工具来使用 SOAP 服务。

服务 WSDL 中定义的类型之一具有以下属性:

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

但是,当请求此属性值为 null 的数据时,它将在原始 XML 中返回为:

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

在反序列化 XML 时会导致以下异常:FormatException: The string '' is not a valid AllXsd value.

我无法修复 SOAP 服务中的错误以更改 XML 响应(如果我是正确的,它应该有 xsd:nil 作为类型)。

什么是好的解决方法,以便它不会引发异常并允许我访问属性值,至少作为字符串?

有什么方法可以覆盖 XML 响应的反序列化?在Reference.cs 文件中将相应的属性类型从DateTime 更改为string 将无济于事(似乎反序列化程序使用了XML 响应中存在的类型信息)。

如果我从Reference.cs 中删除该属性,则不会引发异常,但是我无法访问我需要的属性值。

【问题讨论】:

  • “在 Reference.cs 文件中将相应的属性类型从 DateTime 更改为字符串将无济于事” - 除非在重新生成代理时会出现问题,否则它应该可以工作.执行此操作、重新编译并调用服务时究竟会发生什么?
  • @CodeCaster 我得到了完全相同的异常:/,这就是为什么我提到它没有帮助。只有当我删除该属性时,异常才会消失(连同属性值...)
  • 您是否尝试过修改 WSDL 的本地副本?
  • 不,但据我了解,WSDL 是正确的(对 WSDL 的任何更改也可以对代理类进行),只有 XML 响应不正确(xsi:type 应设置为"xsd:nil")。

标签: c# visual-studio wcf soap service-reference


【解决方案1】:

我能够想出以下解决方法来检查原始 XML 响应并在 WCF 解析它之前对其进行修改。

它基本上用预期的&lt;paymentDate xsi:nil="true"&gt;&lt;/paymentDate&gt; 替换了不正确的&lt;paymentDate xsi:type="xsd:dateTime"&gt;&lt;/paymentDate&gt;

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;
    }
}

【讨论】:

    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2013-04-05
    • 2017-08-22
    相关资源
    最近更新 更多