WCF中的DataContract有什么意义?

当你创build一个WCF项目时,VS.net创build一个模板。

它将一个类添加到iService1.cs文件中:

// Use a data contract as illustrated in the sample below to // add composite types to service operations. [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } 

由于WCF服务可以返回任何用户定义的类,为什么使用DataContract和CompositeType类呢?

我可以返回像这样的东西:

  [OperationContract] MyUserCollection GetUsers(); 

我错过了什么?

DataContract只是服务边界两侧可以理解的types的正式定义。

如果你返回一个“MyUserCollection”对象,那么你的服务的使用者需要引用你的服务/系统的内部,这违反了显式边界的SOA原则。 通过使用DataContract,您将以松散耦合的方式发布返回types的结构。

另一个有趣的事情是,如果你用DataContract装饰你的代码,你对客户端可以看到的东西有很大的控制权,并且必须发送回你的服务。 例如:

 [DataContract] public class SampleClass { [DataMember(IsRequired=true)] public int MyRequiredProperty { get; set; } [DataMember] public int MyOptionalProperty { get; set; } public int MyInternalProperty { get; set; } } 

在上面的例子中,你定义了在接收数据时,你必须有MyRequiredProperty,你可以有或没有MyOptionalProperty。 此外,客户端将永远不会看到MyInternalProperty(例如,这可能是一些有助于内部逻辑的属性,但不希望它在客户端级别显示)。

还有一个重要的用途,你可以改变类的名称和属性。 在序列化和反序列化过程中,这是一个方便的function。

 [DataContract(Name="EmployeeName")] public class Person { [DataMember(Name="FullName")] public string Name { get; set; } [DataMember(Name="HomeAddress")] public string Address { get; set; } } 

为了回答“marc_s”:

“如果你在networking的两端都有.NET,那就好了,如果你有一个Java客户端调用你的服务,如果你把你的数据放在DataContracts中,这些信息就会被存储在WSDL / XSD元数据中,并且可以被使用由.NET以外的客户也是如此。“

我认为这是错误的。 我们来试试这个:

  1. 使用WCF项目的默认示例,在类上使用DataContract属性的类,在成员上使用DataMember,以及返回此types的方法。
  2. build立它并显示wsdl。 xsd包含CompositeType定义。 好。
  3. 现在让我们删除所有的属性DataContract和DataMember
  4. build立它并显示wsdl。 xsd仍然包含ComposityType定义! (使用SCM软件更明显,步骤2和步骤4之间的文件没有区别)

所以Java客户端应该pipe理这个,没有DataContract和DataMember! 我错了还是什么?

我不同意那个说“DataContract只是服务界两边可以理解的types的正式定义”的海报。

这里的关键字是“type”。 在.NET中,types是可以有字段,属性和方法的对象。 但是,当您在WCF服务中使用DataContract装饰类时,结果不是魔法移植到调用代码中的类; 不是由一个长镜头! 在调用代码中,您将有一个“代理”类。 代理类接收代表数据合同内容的XML。 调用代码可以通过代理类来接收这些XML值,但是它不会给调用代码访问类的内部装饰和datacontract

也许不经常使用,我们可以使用[DataContract]来传递私有variables。 如果不使用[DataContract]属性,则DataContractSerializer将序列化/反序列化仅公开可见的types。

 [DataContract] public class SampleClass { [DataMember] private int MyPrivateProperty { get; set; } } 

(注意:如果您正在生成代理,那么私有成员将公开)