With the XmlSerializer
I can have my members in different namespaces to the parent type.
Can I do the same thing with DataContractSerializer
?
I would like the following XML:
<h:Type xmlns:h="http://schemas.e.com/WebServices"
xmlns="http://schemas.e.com/WebServices">
<Member xmlns="http://schemas.e.com/CoreTypes">0</Member>
</h:Type>
Is this possible in with DataContractSerializer
?
You can define subdatacontracts in different namespaces and use them as members of another datacontract, but you can't control the individual member names and/or shapes. The DataContractSerializer
isn't intended to replace XmlSerializer
for fine-grained control of the "shape" of your XML.
While it is true as stated in this answer by nitzmahone that a specific data contract type cannot have declared members in multiple namespaces, it is possible that, in a type hierarchy, derived types can belong to different data contract namespaces than the base types from which they inherit. When this happens, each member will be serialized into the namespace in which it is declared. By constructing an appropriate type hierarchy, XML entities with members in disparate namespaces can be (de)serialized by DataContractSerializer
.
The specific rules are as follows:
If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first in the order.1
Data members are serialized into the data contract namespace of the data member type in which they are declared.
The root namespace of a data contract type is the namespace of its most derived type.
XML elements are (de)serialized in the order specified by Data Member Order. DataContractSerializer
does not allow for data members to be freely reordered during deserialization.2
Collections have their own rules as specified in Collection Types in Data Contracts; this answer does not apply to them.
Thus the XML in the question can be consumed by DerivedType
in the following type hierarchy:
[DataContract(Name = "Base", Namespace = "http://schemas.e.com/CoreTypes")]
public class BaseType
{
[DataMember]
public int Member { get; set; }
}
[DataContract(Name = "Type", Namespace = "http://schemas.e.com/WebServices")]
public class DerivedType : BaseType
{
}
And, in general, any sequence of XML elements in any sequence of namespace(s) can be obtained by applying the rules above to construct an appropriate type hierarchy, offering a workaround that meets the requirement of deserializing elements in different namespaces.
Of course, such a hierarchy might be inconvenient for other reasons, in which case the preferred data model types can be replaced with DTOs by using the data contract surrogate mechanism.
1 Data Member Order.
2 Data Member Order and XML Deserialization