Adding a DataMember to a different namespace to th

2019-05-14 09:49发布

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?

2条回答
Lonely孤独者°
2楼-- · 2019-05-14 10:32

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:

  1. 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

  2. Data members are serialized into the data contract namespace of the data member type in which they are declared.

  3. The root namespace of a data contract type is the namespace of its most derived type.

  4. 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

  5. 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

查看更多
我想做一个坏孩纸
3楼-- · 2019-05-14 10:34

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.

查看更多
登录 后发表回答