何时使用DataContract和DataMember属性?


178

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

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

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

我的服务合同如下所示

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

Answers:


360

由于.NET 3.5 SP1使得很多程序员对[DataContract][DataMember]属性感到不知所措,因此Microsoft使数据协定序列化程序处理所有类(即使没有任何这些属性)也很像旧的XML序列化程序。

因此,从.NET 3.5 SP1开始,您不再需要添加数据协定或数据成员属性-如果您不这样做,则数据协定序列化程序将对类上的所有公共属性进行序列化,就像XML序列化程序一样。

但是:通过不添加这些属性,您将失去许多有用的功能:

  • 如果不使用[DataContract],则无法定义XML命名空间以将数据保留在其中
  • 没有[DataMember],则无法序列化非公共属性或字段
  • 如果没有[DataMember],则无法定义序列化顺序(Order=),DCS将按字母顺序对所有属性进行序列化
  • 不使用[DataMember],则无法为属性(Name=)定义其他名称
  • 没有[DataMember],您将无法定义诸如之类的东西IsRequired=或其他有用的属性
  • 没有的话[DataMember],您不能遗漏某些公共财产-所有公共财产将由DCS序列化。

因此,对于“快速'肮脏”的解决方案,省略[DataContract][DataMember]属性可以工作-但是将它们包含在数据类中仍然是一个好主意-只是为了更明确地说明您在做什么,并让自己访问所有这些没有它们就无法获得的附加功能...


您的意思是默认情况下,所有数据类型在内部都标记为可序列化,我们使用DataContract / DataMember对其进行限制。
Santosh Singh,

2
@Santosh:如果您的类具有一些公共属性,则将由WCF数据合同序列化程序序列化,除非您明确应用[DataContract] / [DataMember] .-然后由您决定要序列化哪些内容并进行100%的决定什么不
marc_s

36
@Arthis:并非完全如此。作为.NET 3.5 SP1的,WCF会愉快地连载类没有任何 [DataContract][DataMember]属性......但只要你开始使用这些属性之一,那么这种“默认”的行为将停止工作-只要你有一个 [DataMember]在你的从那时起,仅对具有此属性的那些属性进行序列化。
marc_s 2012年

4
哦!感谢您澄清这一点!然后,我将进一步进行挖掘!
Arthis

6
hou!摇滚!谢谢!
Arthis

15

就WCF而言,我们可以通过消息与服务器和客户端进行通信。为了传输消息,并且出于安全方面的考虑,我们需要以序列化格式制作数据/消息。

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

让我详细解释一下:

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

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer:-默认顺序与类相同

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

XmlSerializer-XML模式广泛

DataContractSerializer / NetDataContractSerializer:模式受约束

XmlSerializer:-无法支持版本控制

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

XmlSerializer:-与ASMX的兼容性

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

XmlSerializer:-XmlSerializer中不需要此属性

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

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


8

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

Windows Communication Foundation(WCF)默认情况下使用称为数据协定序列化程序的序列化引擎对数据进行序列化和反序列化(将数据与XML相互转换)。所有.NET Framework原语类型(例如整数和字符串)以及某些被视为原语的类型(例如DateTime和XmlElement)都可以在没有其他准备的情况下进行序列化,并被视为具有默认数据协定。许多.NET Framework类型还具有现有的数据协定。

您可以在此处找到完整的文章


2
没错,但这并不能真正回答OP的问题,即为什么数据协定序列化程序也可以在您的类上没有任何[DataContract]和[DataMember]属性的情况下使用....
marc_s

谁能告诉我DataContract的实际用途是什么?-我认为至少部分问题得到了回答。
IAbstract

2

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

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

数据合同可以定义如下:

  • 它描述了往返于服务操作的数据的外部格式

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

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

我们需要包含对项目的System.Runtime.Serialization引用。该程序集包含DataContract和DataMember属性。


2
  1. 数据协定:它指定您的实体类已准备好进行序列化过程。

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


0

同样,当您从http请求中调用时,它将正常运行,但是当您尝试从net.tcp进行调用时,会得到所有此类信息


0

DataMember属性不是必须添加来序列化数据的属性。当未添加DataMember属性时,旧的XMLSerializer会序列化数据。添加DataMember可提供有用的属性,例如订单,名称,必填项,否则无法使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.