XML反序列化成不同的类?

时间:2016-02-27 18:23:30

标签: c# .net vb.net xml-serialization datacontractserializer

我的目标是使用XML数据传输松散地连接两个应用程序。

我可以轻松地以XML格式序列化和反序列化。 但是我可以在App1中从类序列化并在App2中反序列化不同类(与原始类相同的结构)吗?

C#或VB,没关系。 VB中的结构示例:

App1的:

Namespace Transmitter

    <DataContract>
    Public Class DataOut
        <DataMember>
        Public Header As String
        <DataMember>
        Public Content As String
    End Class

End Namespace

App2的:

Namespace Receiver

    <DataContract>
    Public Class DataIn   ' structure actually matches Transmitter.DataOut from App1
        <DataMember>
        Public Header As String
        <DataMember>
        Public Content As String
    End Class

End Namespace

App1中,我可以将Transmitter.DataOut的实例序列化为XML,但是如何将App2中生成的XML读入Receiver.DataIn的实例?我是否需要在Transmitter.DataOut中实施App2?或者这个(我同意很多次有用)功能可以解决吗? 我不希望通过共享相同的类名来限制。

我对如何(“它是否可行?”)的兴趣不一定在源代码中。如果需要,我可以发布我的来源,但它是非常标准的,使用DataContractSerializer

1 个答案:

答案 0 :(得分:2)

是的,你可以这样做。所有必须匹配的是数据合同,而不是基础的.Net类型。来自Data Contract Equivalence

  

对于客户端成功将某种类型的数据发送到服务或成功将数据发送到客户端的服务,发送的类型不一定必须存在于接收端。唯一的要求是两种类型的数据合同是等价的。 (有时,不需要严格等同,如Data Contract Versioning中所述。)

     

要使数据合同等效,它们必须具有相同的命名空间和名称。此外,一方的每个数据成员必须在另一方具有等效的数据成员。

     

要使数据成员等效,它们必须具有相同的名称。此外,它们必须代表相同类型的数据;也就是说,他们的数据合同必须是等价的。

基于合同的序列化程序的一个基本优势是它不要求基础类型相同。这允许实现独立于有线格式,并且还enables communication between completely different architectures - 包括例如Java and .NET

您需要在两个系统中明确设置data contract namespacename,例如:

Namespace Transmitter

    <DataContract(Name:= "Data", [Namespace]:="http://www.MyNameSpace.com")> _
    Public Class DataOut
        <DataMember>
        Public Header As String
        <DataMember>
        Public Content As String
    End Class

End Namespace

或者,您可以使用ContractNamespaceAttribute

为整个程序集设置名称空间
<Assembly:ContractNamespaceAttribute("http://www.MyNameSpace.com", ClrNamespace:="Transmitter")> 

有关详情,请参阅Data Contract Names

另请注意,DataContractSerializerorder sensitive,因此合同中的成员顺序必须匹配。