2

My goal is to loosely connect two applications using XML data transfer.

I can easily serialize and deserialize in XML format. But can I serialize from class in App1 and deserialize in different class (with the same structure as original one) in App2?

C# or VB, doesn't matter. Structure example in 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

In App1, I can serialize instance of Transmitter.DataOut into XML, but how can I read the produced XML in App2 into instance of Receiver.DataIn? Am I required to implement Transmitter.DataOut in App2? Or can this (I agree that many times useful) feature be worked around? I do not want to be restricted by sharing the same class name.

I'm interesed in how-to ("is it viable?") not necessarily in source code. I can post my source if needed, but it is pretty standard one, using DataContractSerializer.

dbc
  • 104,963
  • 20
  • 228
  • 340
miroxlav
  • 11,796
  • 5
  • 58
  • 99

1 Answers1

2

Yes, you can do this. All that has to match are the data contracts, not the underlying .Net types. From Data Contract Equivalence:

For a client to successfully send data of a certain type to a service, or a service to successfully send data to a client, the sent type does not necessarily have to exist on the receiving end. The only requirement is that the data contracts of both types be equivalent. (Sometimes, strict equivalence is not required, as discussed in Data Contract Versioning.)

For data contracts to be equivalent, they must have the same namespace and name. Additionally, each data member on one side must have an equivalent data member on the other side.

For data members to be equivalent, they must have the same name. Additionally, they must represent the same type of data; that is, their data contracts must be equivalent.

One of the basic strengths of a contract-based serializer is that it does not require that the underlying types be identical. This allows implementation to be independent of wire format, and also enables communication between completely different architectures -- including for example Java and .NET.

You will need to explicitly set the data contract namespace and name to be the same in both systems, e.g.:

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

Alternatively, you can set the namespace for the entire assembly using the ContractNamespaceAttribute:

<Assembly:ContractNamespaceAttribute("http://www.MyNameSpace.com", ClrNamespace:="Transmitter")> 

For more, see Data Contract Names.

Also be aware that DataContractSerializer is order sensitive so the order of members in the contracts must match.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • That is a great explanation. Thank you for showing how this could be understood and made. (Yesterday and today I spent many unsuccessful hours studying and trying.) – miroxlav Feb 27 '16 at 20:24