【问题标题】:When to use DataContract and DataMember attributes?何时使用 DataContract 和 DataMember 属性?
【发布时间】:2011-06-17 17:24:51
【问题描述】:

我对 WCF 中的 DataContract 属性感到非常困惑。据我所知,它用于序列化用户定义的类型,如类。我写了一个像这样暴露在客户端的类。

[DataContract]
public class Contact
{
    [DataMember]
    public int Roll { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Address { get; set; }

    [DataMember]
    public int Age { get; set; }
}

它工作正常,但是当我删除 DataContractDataMember 时,它也能正常工作。我不明白为什么它工作正常。谁能告诉我DataContract的实际用途是什么?

我的服务合同是这样的

[ServiceContract]    
public interface IRestServiceImpl
{
    [OperationContract]        
    Contact XmlData(string id);      
}

【问题讨论】:

标签: wcf datacontractserializer datacontract datamember


【解决方案1】:

由于许多程序员对 [DataContract][DataMember] 属性感到不知所措,因此使用 .NET 3.5 SP1,Microsoft 使数据协定序列化程序可以处理所有类 - 即使没有任何这些属性 - 就像旧的 XML 序列化程序一样.

从 .NET 3.5 SP1 开始,您不再必须添加数据协定或数据成员属性 - 如果您不这样做,那么数据协定序列化程序将序列化您的所有公共属性类,就像 XML 序列化程序一样。

但是:如果不添加这些属性,您会失去很多有用的功能:

  • 没有[DataContract],您将无法为您的数据定义一个 XML 命名空间
  • 没有[DataMember],您无法序列化非公共属性或字段
  • 没有[DataMember],您无法定义序列化顺序 (Order=),DCS 将按字母顺序序列化所有属性
  • 没有[DataMember],您无法为您的属性定义不同的名称 (Name=)
  • 没有[DataMember],您无法定义IsRequired= 之类的内容或其他有用的属性
  • 没有[DataMember],您不能遗漏某些公共属性 - 所有公共属性都将由 DCS 序列化

因此,对于“quick'n'dirty”解决方案,放弃[DataContract][DataMember] 属性将起作用 - 但将它们放在您的数据类中仍然是一个好主意 - 只是为了更明确地说明什么你正在做,并让自己访问所有那些没有它们你就无法获得的附加功能......

【讨论】:

  • 您的意思是默认情况下所有数据类型都在内部标记为可序列化,我们使用 DataContract/DataMember 来限制它们。
  • @Santosh:如果您有一个具有一些公共属性的类,那么这些属性将由 WCF 数据协定序列化程序序列化,除非您明确应用 [DataContract]/[DataMember] 。- 那么它是 100%让你说什么被序列化,什么不是
  • @Arthis:这并不完全正确。从 .NET 3.5 SP1 开始,WCF 将很高兴序列化没有 any [DataContract][DataMember] 属性的类...但是一旦您开始使用其中一个属性,那么这种“默认”行为将停止工作 - 只要您的班级中有 single [DataMember],从那时起,那些具有此属性的属性将被序列化。
  • 哦!感谢您澄清这一点!那我再深入一点!
  • 幽后!它摇滚!谢谢漂亮!
【解决方案2】:

在WCF方面,我们可以通过消息与服务端和客户端进行通信。为了传输消息,从安全角度来看,我们需要以序列化格式制作数据/消息。

为了序列化数据,我们使用 [datacontract] 和 [datamember] 属性。 在您的情况下,如果您使用 datacontract WCF 使用 DataContractSerializer 否则 WCF 使用 XmlSerializer 这是默认的序列化技术。

让我详细解释一下:

WCF 基本上支持 3 种类型的序列化:

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer :- 默认顺序与类相同

DataContractSerializer/NetDataContractSerializer :- 默认顺序是字母顺序

XmlSerializer :- XML Schema 很广泛

DataContractSerializer/NetDataContractSerializer :- XML Schema 受到约束

XmlSerializer :- 无法支持版本控制

DataContractSerializer/NetDataContractSerializer :- 可以支持版本控制

XmlSerializer :- 与 ASMX 的兼容性

DataContractSerializer/NetDataContractSerializer :- 与 .NET Remoting 的兼容性

XmlSerializer :- XmlSerializer 中不需要的属性

DataContractSerializer/NetDataContractSerializer :- 此序列化所需的属性

所以你使用什么取决于你的要求......

【讨论】:

    【解决方案3】:

    数据契约是服务和客户端之间的正式协议,它抽象地描述要交换的数据。也就是说,为了进行通信,客户端和服务不必共享相同的类型,只需相同的数据契约。数据契约为每个参数或返回类型精确定义了哪些数据被序列化(转换为 XML)以进行交换。

    Windows Communication Foundation (WCF) 默认使用称为 Data Contract Serializer 的序列化引擎来序列化和反序列化数据(将其转换为 XML 或从 XML 转换)。所有 .NET Framework 基元类型(例如整数和字符串)以及某些被视为基元的类型(例如 DateTime 和 XmlElement)都可以在不进行其他准备的情况下进行序列化,并被视为具有默认数据协定。许多 .NET Framework 类型也有现有的数据协定。

    你可以找到全文here.

    【讨论】:

    • 这一切都很好,但它并没有真正回答 OP 的问题,即为什么数据协定序列化程序在您的类上没有任何 [DataContract] 和 [DataMember] 属性的情况下也可以工作......
    • 谁能告诉我 DataContract 的实际用途是什么? - 我认为至少部分问题得到回答。
    【解决方案4】:

    数据契约是服务和客户端之间的正式协议,抽象地描述了要交换的数据。

    数据契约可以是显式的或隐式的。简单类型如 int、string 等具有隐式数据协定。用户定义的对象是显式或复杂类型,您必须使用 [DataContract] 和 [DataMember] 属性为其定义数据协定。

    数据契约可以定义如下:

    • 它描述了传入和传出服务操作的数据的外部格式

    • 它定义了服务消息中交换的数据的结构和类型

    • 它将 CLR 类型映射到 XML 架构
    • 它定义了数据类型如何被序列化和反序列化。通过序列化,您可以将对象转换为可以通过网络传输的字节序列。通过反序列化,您可以从调用应用程序接收到的字节序列重新组装一个对象。
    • 这是一个版本控制系统,可让您管理对结构化数据的更改

    我们需要在项目中包含 System.Runtime.Serialization 引用。此程序集包含 DataContract 和 DataMember 属性。

    【讨论】:

      【解决方案5】:
      1. 数据契约:它指定您的实体类已准备好进行序列化过程。

      2. 数据成员:指定特定字段是数据契约的一部分,可以序列化。

      【讨论】:

        【解决方案6】:

        此外,当您从 http 请求调用时,它会正常工作,但是当您尝试从 net.tcp 调用时,您会得到所有这些东西

        【讨论】:

          【解决方案7】:

          DataMember 属性不是强制添加以序列化数据。当不添加 DataMember 属性时,旧的 XMLSerializer 会序列化数据。添加 DataMember 提供了有用的属性,如 order、name、isrequired,否则无法使用。

          【讨论】:

            【解决方案8】:

            数据将在服务内传输和处理并存储值,因此在 WCF 术语中它们被称为“数据契约”。

            类的每个成员;即,数据契约称为“数据成员”,它们也将用属性进行装饰。

            Source

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-03
              • 2012-06-18
              • 2012-12-14
              • 1970-01-01
              相关资源
              最近更新 更多