1

ポリモーフィック オブジェクトの配列を逆シリアル化している 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:MasterNodeとが含まれていることが関連している可能性がありcmtypes:PhysicalNodeます。

編集:スタブとメッセージが一緒にならない可能性がありますか? 私が理解しているように、スタブは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 に動作を挿入することで、何とか修正できると思いますか? 私の大きな問題は、サーバー側を変更する可能性がまったくないことです...

4

1 に答える 1

0

これのトラブルシューティングは難しいでしょう。私が試みることの 1 つは、XmlSerializerを使用して逆シリアル化できるかどうかを確認し、問題のある型が得られるまでメッセージの削減を開始することです。

于 2012-05-03T14:56:22.887 に答える