【问题标题】:WCF - MessageContract members (MessageBodyMember) ignored when deserialisingWCF - 反序列化时忽略 MessageContract 成员 (MessageBodyMember)
【发布时间】:2016-10-06 08:35:36
【问题描述】:

我正在使用 SOAP 服务,并成功接收到响应。

很遗憾,WCF 没有反序列化响应 POCO 的成员。

使用诊断跟踪,响应中的每个成员都会出现以下错误:

Description     An unrecognised element was encountered in the XML during deserialisation which was ignored.
Element         :partnerId

请你看看我哪里出错了?

代码如下:

服务合同

[ServiceContract(Namespace = "https://foo.com/services/mediationV1/", ConfigurationName = "IPlatformPortType")]
public interface IPlatformPortType
{
    [OperationContract(Action = "https://foo.com/services/foo_bar_HeartBeatV1/", ReplyAction = "*")]
    HeartBeatResponse SendHeartBeat(HeartbeatRequest request);
}

POCO 请求

[MessageContract(IsWrapped = true,
    WrapperName = "foo_bar_HeartBeatRequest",
    WrapperNamespace = "https://foo.com/schemas/fooV1/")]
public class HeartbeatRequest
{
    [MessageBodyMember(Namespace = "https://foo.com/schemas/fooV1/", Order = 0)]
    public string transactionId { get; set; }

    [MessageBodyMember(Namespace = "https://foo.com/schemas/fooV1/", Order = 2)]
    public string partnerId { get; set; }
}

SOAP 请求

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">https://foo.com/services/foo_bar_HeartBeatV1/</a:Action>
        <a:MessageID>urn:uuid:73efa49e-f2b3-4f5d-b750-6784b1becfbc</a:MessageID>
        <a:ReplyTo>
            <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
    </s:Header>
    <s:Body>
        <foo_bar_HeartBeatRequest xmlns="https://foo.com/schemas/fooV1/">
            <transactionId>f642df34-d328-4d76-9a9f-3cf64bdef71d</transactionId>
            <partnerId>bob</partnerId>
        </foo_bar_HeartBeatRequest>
    </s:Body>
</s:Envelope>

POCO 响应

[MessageContract(IsWrapped = true,
    WrapperName = "foo_bar_HeartBeatResponse",
    WrapperNamespace = "https://foo.com/schemas/fooV1/")]
public class HeartBeatResponse
{
    [MessageBodyMember(Namespace = "https://foo.com/schemas/fooV1/", Order = 2)]
    public string transactionId { get; set; }

    [MessageBodyMember(Namespace = "https://foo.com/schemas/fooV1/", Order = 3)]
    public int requestStatus { get; set; }
}

SOAP 响应

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:MessageID>urn:uuid:b66497fd-4e95-458c-8772-c8bfc0decb51</wsa:MessageID>
        <wsa:Action>urn:mediateResponse</wsa:Action>
        <wsa:RelatesTo>urn:uuid:73efa49e-f2b3-4f5d-b750-6784b1becfbc</wsa:RelatesTo>
    </soapenv:Header>
    <soapenv:Body>
        <ns:foo_bar_HeartBeatResponse xmlns:ns="https://foo.com/schemas/fooV1/">
            <transactionId>f642df34-d328-4d76-9a9f-3cf64bdef71d</transactionId>
            <requestStatus>1</requestStatus>
        </ns:foo_bar_HeartBeatResponse>
    </soapenv:Body>
</soapenv:Envelope>

更新

根据@TomRedfern 的评论,我尝试用 DataContract 替换所有 MessageContract 属性。

不幸的是,这剥夺了我通知 seriliaser POCO 是 包装器 的能力,导致 SOAP 如下所示:

<s:Body>
    <SendHeartBeat xmlns="https://foo.com/services/fooV1/">
        <request xmlns:b="https://foo.com/schemas/fooV1/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <b:transactionId>7085587a-4275-49ad-9aa9-5b413afcbe62</b:transactionId>
            <b:partnerId>bob</b:partnerId>
        </request>
    </SendHeartBeat>
</s:Body>

注意节点的名称现在是操作的名称(SendHeartBeat),它的子节点是该操作的参数名称。

我无法控制 WSDL,所以这不起作用。

【问题讨论】:

  • 你有什么理由使用消息合约而不是数据合约?
  • @TomRedfern 不是真的 - 我对 WCF 堆栈相当不熟悉。我将尝试使用 DataContract 属性,看看我在哪里。感谢您的建议。
  • 已尝试您的建议并更新了问题,@TomRedfern。

标签: wcf soap deserialization


【解决方案1】:

经过一天的反复试验,我终于让反序列化正常工作了。

对于 POCO 的每个成员,我做了以下事情:

  • 添加一个 XmlElementAttribute。
  • 将 Form 参数添加到 XmlElementAttribute,值为 XmlSchemaForm.Unqualified。
  • 从 MessageBodyMemberAttribute 中移除 Namespace 参数并添加到 XmlElementAttribute。
  • 删除了 MessageBodyMemberAttribute 中的所有现有参数。

这里是正确响应POCO:

[MessageContract(IsWrapped = true,
    WrapperName = "foo_bar_HeartBeatResponse",
    WrapperNamespace = "https://foo.com/schemas/fooV1/")]
public class HeartBeatResponse
{
    [MessageBodyMember]
    [XmlElement(Form = XmlSchemaForm.Unqualified, Namespace = "https://foo.com/schemas/fooV1/")]
    public string transactionId { get; set; }

    [MessageBodyMember]
    [XmlElement(Form = XmlSchemaForm.Unqualified, Namespace = "https://foo.com/schemas/fooV1/")]
    public int requestStatus { get; set; }
}

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 2013-04-07
    • 2014-02-01
    • 2014-05-11
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多