tags:

views:

6937

answers:

4

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 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 a WCF service can return any user defined class, why use a DataContract and CompositeType class?

I can return something like:

 [OperationContract]
MyUserCollection GetUsers();

What am I missing?

+14  A: 

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.

Guy Starbuck
My WCF is being consumed by apps written by me, so in all practical purposes it should be ok (to voilate SOA). Do you concurr?
Blankman
You probably could, but why would you want to? Adding the attribute is painless and is the recommended way to work with WCF.
Scott Dorman
Scott, so I just add my MyUserCollection to the CompositeType class and bingo!?
Blankman
You may need to add a [KnownType(MyUserCollection)] attribute to the CompositeType class. I would try it first without one; if it doesn't work you will get an exception saying to add MyUserCollection to the list of known types, in which case just add the attribute.
Scott Dorman
+3  A: 

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).

Wagner Silveira
A: 

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 datacontract. The calling code can receive these XML values thru the proxy class, but it does not give the calling code access to the innards of the class decorate with datacontract.

Rice Flour Cookies
A: 

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 :

  1. Use the default example of WCF project with a class with DataContract attributes on classes and DataMember on members, and a method which returns this type.
  2. Build it and display the wsdl. The xsd contains the CompositeType definition. OK.
  3. Now let's remove all attributes DataContract and DataMember
  4. Build it and display the wsdl. The xsd still contains the ComposityType definition ! (it is more obvious with a SCM soft, which shows no difference in files between steps 2 and 4)

So a Java client should manage this, without DataContract and DataMember ! Am I wrong or what ?

WolveFred