4

我有一些简单的 POCO 对象:

public class ProductCategoryDTO
{
        public string Name { get; set; }
        public DateTime ModifiedDate { get; set; }
}

由于有时字段顺序很重要(例如,如果发送到 Infopath 表单),我需要在序列化时保持元素顺序。

现在我很困惑,我应该为类和每个字段使用什么属性。我知道:

  • DataContractSerializer 使用 [DataContract] 和 [DataMember(Order = n)]
  • XMLSerializer 使用 [Serializable] 和 [XmlElementAttribute(Order = n)]。

那么如果我想同时支持 XMLSerializer 和 DataContractSerializer 使用什么属性,那么它可以在 WCF 或 ASP 中使用。网页服务?

4

3 回答 3

6

严格来说,你不需要为任何一个使用任何属性;-p 它曾经是DataContractSerializer需要[DataContract]/ [DataMember](并且绝对应该使用它们),但你可以不使用它(但它的行为方式非常可疑类似于BinaryFormatter)。同样,除非您想控制事物,否则不需要任何XmlSerializer东西但是,您应该注意一些差异:

  • XmlSerializer要求(并使用)公共无参数构造函数;DataContractSerializer 不使用构造函数(根本)。因此请注意这一点,并且不要(对于 WCF)依赖于 ctor 中的代码 - 如果您有必要的初始化代码,请为 WCF 使用序列化回调。
  • XmlSerializer要求公共字段(yeuch)或公共属性与两者getset甚至对于列表);DataContractSerializer将很高兴地针对私有成员、具有(例如) publicget和 private的属性set以及没有`set 的集合(只要您的类型初始化它)。
  • XmlSerializer要求公共类型;IIRCDataContractSerializer不那么挑剔

所以是的;您可以同时支持这两种序列化程序,并且可以并行添加任意数量的属性,但如果您想要完全兼容,请注意上述内容。

另一种选择是只使用XmlSerializer; 您可以XmlSerializer使用[XmlSerialzerFormat]. 这两个选项都支持继承, via[XmlInclude][KnownType].

最后,请注意,如果您实施IXmlSerializable,这将优先于任何一个,但很难做到正确。除非必须,否则不要这样做。

于 2009-12-19T18:39:59.637 回答
3

如果你真的必须的话,我看不出有什么理由不能将两个属性都放在类和成员属性上。看起来不太好,但如果它适合你,那很好!

[DataContract(Namespace="....")]
[XmlType]
public class ProductCategoryDTO
{
        [DataMember(Order=1)]
        [XmlElementAttribute(Order=1)]
        public string Name { get; set; }

        [DataMember(Order=2)]
        [XmlElementAttribute(Order=2)]
        public DateTime ModifiedDate { get; set; }
}
于 2009-12-19T17:06:04.963 回答
1

XML 元素的顺序应由 WSDL 规定,您无需担心。从 .NET 3.5 SP1 开始,您不再需要使用DataContractAttributeDataMemberAttribute。序列化程序将自动包含所有公共属性。就XmlSerializer而言,SerializableAttribute没有任何作用。此属性用于BinaryFormatter的二进制序列化。因此,要恢复,您可以将该类保留为 POCO,在 WCF 或 ASP.NET Web 服务中公开它,并让客户端根据 WSDL 使用它。

于 2009-12-19T16:35:20.157 回答