VS.net creates a template when you create a WCF project.
It adds a class to the iService1.cs file:
// Use a data contract as illustrated in the sampl
The DataContract is just a formal definition of a type that can be understood on both sides of the service boundary.
If you return, as in your example, a "MyUserCollection" object, the consumers of your service will need to reference the innards of your service/system, which is a violation of the SOA tenet of explicit boundaries. By using a DataContract, you are publishing the structure of your return types in a loosely-coupled way.
I disagree with the poster who said "The DataContract is just a formal definition of a type that can be understood on both sides of the service boundary."
The keyword here is "type". In .NET, a type is an object that can have fields, properties, and methods. However, when you decorate a class with DataContract
in your WCF service, the result is not the class being magically transplanted into the calling code; not by a long shot! In the calling code, you will have a "proxy" class. The proxy class receives XML that represents the contents of the data contract. The calling code can receive these XML values through the proxy class, but it does not give the calling code access to the innards of the class decorate with datacontract
.
For answering to "marc_s" :
"If you have .NET on both ends of the wire, that's just fine. What if you have a Java client calling your service? If you put your data inside DataContracts, that information gets stored in the WSDL/XSD metadata and can be used by clients other than .NET, too."
I think it is false. Let's try to do this :
So a Java client should manage this, without DataContract and DataMember ! Am I wrong or what ?
Another interesting thing to notice, is if you decorate your code with DataContract, you have a lot of control about what the client can see and must send back to your service. For example:
[DataContract]
public class SampleClass
{
[DataMember(IsRequired=true)]
public int MyRequiredProperty { get; set; }
[DataMember]
public int MyOptionalProperty { get; set; }
public int MyInternalProperty { get; set; }
}
On the example above, you defined that when receiving data, you MUST have MyRequiredProperty, and you can have or not MyOptionalProperty. Also, the client will never see MyInternalProperty (this can be for example some property that helps with your logic internally, but you don't want it being exposed at the client level).
Perhaps not often used, we could use [DataContract] to pass through private variables. The DataContractSerializer will serialize/deserialize only publicly visible types if [DataContract] attribute is not used.
[DataContract]
public class SampleClass
{
[DataMember]
private int MyPrivateProperty { get; set; }
}
(Note: If you are generating a proxy then private members are exposed as public)
There is another important use, You can change the Name of class and properties. It's a handy feature during serialization and deserialization.
[DataContract(Name="EmployeeName")]
public class Person
{
[DataMember(Name="FullName")]
public string Name { get; set; }
[DataMember(Name="HomeAddress")]
public string Address { get; set; }
}