使用WCF DataContractSerializer对嵌套对象树进行反序列化

时间:2014-12-09 16:56:55

标签: c# wcf soap deserialization datacontractserializer

我有以下SOAP XML响应

<startProcessResponseDDWEBCall xmlns="http://eclipse.org/stardust/models/generated/OmniLinkServices">
     <ProcessInstanceOid>13430</ProcessInstanceOid>
     <Return>
        <DDWEBCallResponseData>
           <DDWEBCallOutput xmlns="http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallOutput">
              <CommonResponse xmlns=""/>
              <reportContent xmlns=""><![CDATA[<HTML><BODY><P>The OmniPlus Host Server process DDWEB had the following error:  </P><P><TEXT="FF000">E23 TX00087 Textfile not found: TestScript @ 000003\\\                                                                                                    </TEXT></P><P>processing terminated</P></BODY></HTML>]]></reportContent>
           </DDWEBCallOutput>
        </DDWEBCallResponseData>
     </Return>
  </startProcessResponseDDWEBCall>

这是WCF Web服务调用响应的SOAP主体。我有以下对象层次结构来表示响应

[DataContract(Namespace="http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallOutput")]
public class OmniLinkExecuteScriptOutput
{   
    public string CommonResponse { get; set; }

    [DataMember(Name = "reportContent")]
    public string ReportContent { get; set; }
}

[DataContract(Namespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices")]
public class OmniLinkExecuteScriptResponseData
{    
    [DataMember(Name="DDWEBCallOutput")]
    public OmniLinkExecuteScriptOutput Output { get; set; }
}

[DataContract(Namespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices")]    
public class OmniLinkExecuteScriptReturn
{ 
    [DataMember(Name="DDWEBCallResponseData")]
    public OmniLinkExecuteScriptResponseData ReponseData { get; set; }
}

[MessageContract(WrapperName = "startProcessResponseDDWEBCall", WrapperNamespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices", IsWrapped = true)]
public class OmniLinkExecuteScriptResponse
{
    [MessageBodyMember(Name = "ProcessInstanceOid", Namespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices")]
    public string ProcessInstanceOid { get; set; }

    [MessageBodyMember(Name = "Return", Namespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices")]
    public OmniLinkExecuteScriptReturn Return { get; set; }
}

对象OmniLinkExecuteScriptResponse是方法调用的返回类型。除了最内层的对象,表示DDWEBCallOutput节点的对象之外,所有内容都被反序列化。我没有在WCF管道中看到任何错误,并且OmniLinkExecuteScriptResponseData对象上的Output属性值始终为null。

有人能说出我做错了吗?

1 个答案:

答案 0 :(得分:0)

您的问题是您在类层次结构中的错误级别应用[DataContract(Namespace = "...")]属性。此属性控制类型实例的所有数据成员序列化的名称空间,并且如果实例序列化,则控制根元素名称空间。

因此,您需要执行以下操作:

// Its members are in the empty namespace
[DataContract(Namespace = "")] 
public class OmniLinkExecuteScriptOutput
{
    [DataMember]
    public string CommonResponse { get; set; }

    [DataMember(Name="reportContent")]
    public string ReportContent { get; set; }
}

// Its members are in the DDWEBCallOutput namespace
[DataContract(Namespace = "http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallOutput")] 
public class OmniLinkExecuteScriptResponseData
{
    [DataMember(Name = "DDWEBCallOutput")]
    public OmniLinkExecuteScriptOutput Output { get; set; }
}

// Its members are in the OmniLinkServices namespace
[DataContract(Namespace = "http://eclipse.org/stardust/models/generated/OmniLinkServices")] 
public class OmniLinkExecuteScriptReturn
{
    [DataMember(Name = "DDWEBCallResponseData")]
    public OmniLinkExecuteScriptResponseData ReponseData { get; set; }
}

OmniLinkExecuteScriptResponse可以保持不变。