WCF中的DataContract有什么意义?

时间:2008-11-19 19:14:32

标签: wcf

VS.net在您创建WCF项目时创建模板。

它为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();

我错过了什么?

6 个答案:

答案 0 :(得分:51)

DataContract只是一种可以在服务边界两侧理解的类型的正式定义。

如果在示例中返回“MyUserCollection”对象,则服务的使用者将需要引用服务/系统的内部,这违反了明确边界的SOA原则。通过使用DataContract,您将以松散耦合的方式发布返回类型的结构。

答案 1 :(得分:26)

另一个有趣的事情是,如果您使用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(例如,这可能是一些内部有助于您的逻辑的属性,但您不希望它在客户端级别公开)。

答案 2 :(得分:11)

还有另一个重要用途,您可以更改类和属性的名称。在序列化和反序列化过程中,它是一个方便的功能。

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

   [DataMember(Name="HomeAddress")]
   public string Address { get; set; }
}

答案 3 :(得分:2)

我不同意海报说“DataContract只是一种可以在服务边界两侧理解的类型的正式定义。”

这里的关键字是“type”。在.NET中,类型是可以包含字段,属性和方法的对象。但是,当您在WCF服务中用DataContract修饰一个类时,结果不是将该类神奇地移植到调用代码中;不是由一个长镜头!在调用代码中,您将拥有一个“代理”类。代理类接收表示数据协定内容的XML。调用代码可以通过代理类接收这些XML值,但它 not 使用datacontract赋予调用类内部装饰的调用代码访问权。

答案 4 :(得分:2)

回答“marc_s”:

  

“如果你的两端都有.NET   电线,这很好。如果你怎么办   有一个Java客户端调用你的   服务?如果你把数据放在里面   DataContracts,该信息得到   存储在WSDL / XSD元数据中   可供除客户以外的客户使用   .NET也是。“

我认为这是错误的。我们试着这样做:

  1. 使用WCF的默认示例 带有课程的项目 类上的DataContract属性 和成员上的DataMember,以及 返回此类型的方法。
  2. 构建它并显示wsdl。 xsd包含CompositeType定义。行。
  3. 现在让我们删除所有属性DataContract和DataMember
  4. 构建它并显示wsdl。 xsd仍然包含ComposityType定义! (使用SCM软件更明显,在步骤2和4之间没有显示文件差异)
  5. 所以Java客户端应该管理它,没有DataContract和DataMember!我错了还是什么?

答案 5 :(得分:0)

也许不经常使用,我们可以使用[DataContract]来传递私有变量。如果未使用[DataContract]属性,DataContractSerializer将仅对公开可见的类型进行序列化/反序列化。

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

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