【问题标题】:Problems with WCF deserialising SOAP array containing polymorphic objectsWCF 反序列化包含多态对象的 SOAP 数组的问题
【发布时间】:2012-05-03 14:11:59
【问题描述】:

我对反序列化多态对象数组的 WCF Web 服务有疑问。服务器端不是 WCF,但我从 WSDL 创建了存根。 WSDL 中的重要部分是

<complexType name="NodeList">
    <sequence>
        <element name="data" type="cmtypes:Node" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
    </sequence>
</complexType>

<complexType name="Device">
    <sequence>
        <element name="uniqueKey" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1"/>
        <element name="revision" type="xsd:string" minOccurs="1" maxOccurs="1"/>
        [...}
    </sequence>
</complexType>

<complexType name="Node">
    <complexContent>
        <extension base="cmtypes:Device">
            <sequence>
                <element name="cmdaemonUrl" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                <element name="networks" type="cmtypes:NetworkInterfaceList" minOccurs="0" maxOccurs="1" nillable="true"/>
                [...]
            </sequence>
        </extension>
    </complexContent>
</complexType>

<complexType name="MasterNode">
    <complexContent>
        <extension base="cmtypes:Node">
            <sequence>
            </sequence>
        </extension>
    </complexContent>
</complexType>

VS 为列表创建了以下类型:

[System.Xml.Serialization.SoapIncludeAttribute(typeof(MasterNode))]
[System.Xml.Serialization.SoapIncludeAttribute(typeof(SlaveNode))]
[System.Xml.Serialization.SoapIncludeAttribute(typeof(VirtualSMPNode))]
[System.Xml.Serialization.SoapIncludeAttribute(typeof(VirtualNode))]
[System.Xml.Serialization.SoapIncludeAttribute(typeof(PhysicalNode))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="http://www.brightcomputing.com/cmtypes.xsd")]
public partial class Node : Device {

    private string cmdaemonUrlField;

    [...]
}

但是,如果我收到一条包含主节点的消息,例如

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cmtypes="http://www.brightcomputing.com/cmtypes.xsd" xmlns:cmdevice="http://www.brightcomputing.com/cmdevice.wsdl">
    <s:Header xmlns:s="http://www.w3.org/2003/05/soap-envelope"></s:Header>
    <SOAP-ENV:Body>
        <cmdevice:getNodesResponse SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
            <nodes xsi:type="cmtypes:NodeList" xmlns="">
                <data xsi:type="cmtypes:MasterNode">
                    <uniqueKey xsi:type="xsd:unsignedLong">38654705666</uniqueKey>
                    <revision xsi:type="xsd:string"></revision>
                    <modified xsi:type="xsd:boolean">false</modified>
                    <toBeRemoved xsi:type="xsd:boolean">false</toBeRemoved>
[...]

整个东西都爆炸了,System.ServiceModel.CommunicationException 说“反序列化操作'getNodes'的回复消息正文时出错。”和“对象不能存储在这种类型的数组中。”在内部异常中。为什么?我可以做些什么来解决这个问题(存根生成)?

由于 WCF/SOAP 知识非常有限,我完全没有任何线索,因此感谢您提供任何帮助。

最好的问候, 克里斯托夫

编辑:响应实际上包含不同的多态类型的“数据”元素可能是相关的,即cmtypes:MasterNodecmtypes:PhysicalNode

编辑: 会不会是 Stub 和 Message 不在一起?据我了解,存根需要一个 data 属性,它是一个数组:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="http://www.brightcomputing.com/cmtypes.xsd")]
public partial class NodeList : object, System.ComponentModel.INotifyPropertyChanged {

    private Node[] dataField;

    /// <remarks/>
    [System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
    public Node[] data {
        get {
            return this.dataField;
        }
        set {
            this.dataField = value;
            this.RaisePropertyChanged("data");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

但是,在我的回答中,我得到一个 NodeList 直接包含一系列 data 元素,这些元素实际上是节点或派生自节点:

<cmdevice:getNodesResponse SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
    <nodes xsi:type="cmtypes:NodeList" xmlns="">
        <data xsi:type="cmtypes:MasterNode">
            <uniqueKey xsi:type="xsd:unsignedLong">38654705666</uniqueKey>

            [...]
        </data>
        <data xsi:type="cmtypes:PhysicalNode">
            <uniqueKey xsi:type="xsd:unsignedLong">38654705669</uniqueKey>
            [...]
        </data>
    [...]

你认为我可以通过在 WCF 中注入行为来解决这个问题吗?我最大的问题是我绝对不可能改变服务器端......

【问题讨论】:

  • cmtypes:NetworkInterfaceList 的定义在哪里?
  • 它在 WSDL 中。为简洁起见,我省略了它(以及许多其他内容),但如果它很重要,我可以发布它。
  • 请发布整个 wsdl(包括引用的模式)和整个返回soap。如果是保密的,你也可以给我发邮件。
  • 问题是完整的 WSDL 只是超出了 Stackoverflow 上允许的消息大小。不过我已经上传到网盘了:skydrive.live.com/…
  • 你能上传 .wsdl 和引用的 .xsd 文件吗? .wsdl 还不够。引用的brightcomputing.com/cmtypes.xsd 只是一个URI,而不是URL。

标签: wcf soap wsdl


【解决方案1】:

对此进行故障排除会很困难。我会尝试的一件事是使用XmlSerializer 来查看它是否可以反序列化,然后开始减少消息,直到你得到有问题的类型。

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2018-12-18
    • 2013-02-03
    • 2019-12-07
    相关资源
    最近更新 更多