将DataMember添加到DataContract的不同命名空间

时间:2009-11-10 05:09:06

标签: serialization namespaces datacontract datacontractserializer datamember

使用XmlSerializer我可以将不同命名空间中的成员添加到父类型中。

我可以使用DataContractSerializer做同样的事情吗?

我想要以下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>

是否可以使用DataContractSerializer

2 个答案:

答案 0 :(得分:1)

您可以在不同的命名空间中定义子数据并将其用作另一个数据提取的成员,但您无法控制各个成员名称和/或形状。 DataContractSerializer并非旨在取代XmlSerializer,以便对XML的“形状”进行细粒度控制。

答案 1 :(得分:0)

根据this answer nitzmahone所述,虽然特定数据协定类型不能在多个名称空间中声明成员,但是在层次结构类型中>,派生类型与其所属的基本类型可以属于不同的数据协定名称空间。发生这种情况时,每个成员将被序列化到声明的名称空间中。通过构造适当的类型层次结构,可以用DataContractSerializer对(具有)不同名称空间中的成员的XML实体进行反序列化。

具体规则如下:

  1. 如果数据协定类型是继承层次结构的一部分,则其基本类型的数据成员始终按顺序排列。 1

  2. 数据成员被序列化到声明它们的数据成员类型的数据协定名称空间中。

  3. 数据协定类型的根名称空间是其最派生类型的名称空间。

  4. XML元素按照Data Member Order指定的顺序进行反序列化。 DataContractSerializer不允许在反序列化期间随意重新排序数据成员。 2

  5. 集合有自己的规则,如Collection Types in Data Contracts中所指定;此答案不适用于他们。

因此,DerivedType在以下类型层次结构中可以使用问题中的XML:

[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
{
}

而且,通常,可以通过应用上述规则来构造适当的类型层次结构,来获得名称空间中任何序列中的XML元素中的任何序列,从而提供一种满足不同名称空间中的元素反序列化要求的解决方法。

当然,由于其他原因,这样的层次结构可能会带来不便,在这种情况下,可以使用DTOs机制将首选数据模型类型替换为data contract surrogate


1 Data Member Order

2 Data Member Order and XML Deserialization