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

3

使用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个回答

1

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


那么你是在说这不能做吗?还是可以做,但不应该这样做。 我应该回到使用XmlSerializer吗? - ryancrawcour
基本上,DataContracts并不是为了精细控制而设计的——它们是用于在管道的两端都是WCF时进行“快速、简单和可重复”的操作。XmlSerializer和WCF可以很好地配合使用——它只是默认使用DataContractSerializer。 - nitzmahone

0

正如此答案所述,特定的数据契约类型不能在多个命名空间中声明成员,但在类型层次结构中,派生类型可以属于不同的数据契约命名空间,而不同于它们继承的基类型。当发生这种情况时,每个成员将被序列化到其声明的命名空间中。通过构建适当的类型层次结构,具有不同命名空间成员的 XML 实体可以被DataContractSerializer(反)序列化。

具体规则如下:

  1. 如果数据合同类型是继承层次结构的一部分,则基类型的数据成员始终排在顺序的最前面。

  2. 数据成员被序列化到它们声明的数据成员类型的数据合同命名空间中。

  3. 数据合同类型的根命名空间是其最派生类型的命名空间。

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

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

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

[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


1 数据成员顺序

2 数据成员顺序和XML反序列化


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接