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();
我错过了什么?
答案 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也是。“
我认为这是错误的。我们试着这样做:
所以Java客户端应该管理它,没有DataContract和DataMember!我错了还是什么?
答案 5 :(得分:0)
也许不经常使用,我们可以使用[DataContract]来传递私有变量。如果未使用[DataContract]属性,DataContractSerializer将仅对公开可见的类型进行序列化/反序列化。
[DataContract]
public class SampleClass
{
[DataMember]
private int MyPrivateProperty { get; set; }
}
(注意:如果您正在生成代理,则私有成员将公开为公开)