What is the point of a DataContract in WCF?

VS.net creates a template when creating a WCF project.

It adds a class to the iService1.cs file:

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

Since the WCF service can return any custom class, why use the DataContract and CompositeType classes?

I can return something like:

  [OperationContract] MyUserCollection GetUsers(); 

What am I missing?

+49
wcf
Nov 19 '08 at 19:14
source share
6 answers

A DataContract is simply a formal type definition that can be understood on both sides of the service boundary.

If you return, as in your example, to the "MyUserCollection" object, the consumers of your service will have to refer to the interiors of your service / system, which violates the SOA principle with explicit boundaries. Using a DataContract, you arbitrarily publish the structure of the return types.

+51
Nov 19 '08 at 19:17
source share

Another interesting thing to notice: if you decorate your DataContract code, you have a lot of control over 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; } } 

In the above example, you have determined that when receiving data you MUST have MyRequiredProperty, and you may or may not have MyOptionalProperty. In addition, the client will never see MyInternalProperty (it may be, for example, some property that helps your logic internally, but you do not want it to be displayed at the client level).

+26
Nov 20 '08 at 9:26 a.m.
source share

There is another important use; you can change the class name and properties. This is a convenient feature for 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; } } 
+11
Apr 05 2018-11-11T00:
source share

I disagree with the poster, which said: "DataContract is just a formal type definition 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 the DataContract class in your WCF service, the result is not a class magically transplanted to the calling code; not at all! In the calling code, you will have a proxy class. The proxy class receives XML, which represents the contents of the data contract. The calling code can accept these XML values ​​through a proxy class, but it does not give the code access to the internal properties of the class, decorated with a DataContract .

+2
Jul 20 '10 at 16:59
source share

To reply 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 provider? If you put your data inside DataContracts, this information gets stored in the WSDL / XSD metadata and can be used non-.NET clients too. "

I think this is not true. Try to do this:

  • Use the default WCF example project with a class with DataContract attributes for classes and DataMember for members, as well as a method that returns this type.
  • Create it and show wsdl. Xsd contains the definition of CompositeType. OK
  • Now remove all DataContract and DataMember attributes
  • Create it and show wsdl. Xsd still contains a ComposityType definition! (this is more apparent with SCM soft, which does not show the difference between files between steps 2 and 4).

Thus, the Java client must manage this, without DataContract and DataMember! Am I wrong or what?

+2
Aug 6 '10 at 20:17
source share

Perhaps not often used, we could use [DataContract] to pass through private variables. DataContractSerializer will only serialize / deserialize public types if the [DataContract] attribute is not used.

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

(Note: If you are creating a proxy server, then private members are displayed as public).

0
Feb 08 '13 at 8:51
source share



All Articles