views:

691

answers:

3

I am a newbie in WCF, currently I am developing a TCP WCF service and I am not sure that I understand passing parameters correctly or not so I recommend you to comment and give a standardized way.

To get things clear I developed a small service for testing purpose that has single method and depends on an external .Net dll that exposes single class. The service contract code

    [ServiceContract]
    public  interface IMyService
    {
        [OperationContract]
        int Test1(actionType at, calculationType ct, action a);
        [OperationContract]
        int Test2(DataSeries s);
    }

Where actionType,calculationType,action are enums declared inside the the external dll and DataSeries is a class declared inside the dll.

The origianl defination for the DataSeries class in the dll is marked by [Serializable] only and no [DataMember] on its members.

I am using the 3rd dll on the client and server side, my surprise was both applications working fine without putting [DataContract] on the DataSeries class and without using any of [EnumMember] inside enums, [DataMember] inside class.

So what is going on?

Another Experiment:

Removing the 3rd party from the client side and using the service as it is I found that the vs2008 generates the enums and the DataSeries class and markes them with the proper attributes? like

    [System.CodeDom.Compiler.GeneratedCodeAttribute      ("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="actionType",  Namespace="http://schemas.datacontract.org/2004/07/DBInterface")]
    public enum actionType : int {

        [System.Runtime.Serialization.EnumMemberAttribute()]
        All = 0,

        [System.Runtime.Serialization.EnumMemberAttribute()]
        Buy = 1,

        [System.Runtime.Serialization.EnumMemberAttribute()]
        Sell = 2,
    }
A: 

So for me I use [DataContract]s, and pass a single parameter in, and return a data contract back.

This gives more flexibility, as I can extend the data contract with new, optional attributes to the data contract, without breaking any existing clients.

Enums I also create Data Contacts for; because I can then do the same, extending the enum without breaking anything, and I can control the namespace.

[DataContract(Namespace = "http://namespace.mydomain.com/2009/05", Name = "ReferenceTypeData")]
public enum GenderEnum
{
    [EnumMember()]
    Unknown = 0,
    [EnumMember()]
    Male = 1,
    [EnumMember()]
    Female = 2
}

You must then mark the service contract with

[ServiceKnownType(typeof(GenderEnum))]
public interface IServiceContract
{
    ....
}
blowdart
But without using DataContract or any attributes, I found the client side working correctly
Ahmed Said
+1  A: 

DataContract, DataMember and EnumMember attributes are used by the DataContractSerializer (usually basicHttpBinding or wsHttpBinding). If you are exposing an endpoint with TCP binding (netTcpBinding) only SerializableAttribute is required. Note that with DataContractSerializer you could only add SerializableAttribute to your classes and it will automatically serialize all fields.

I would recommend you the following: if you want your service to be interoperable, use basicHttpBinding and mark your classes with DataContract and DataMember attributes. If your client is a .NET application, use netTcpBinding and mark your classes with SerializableAttribute.

You could also read this post for comparison between different bindings.

Darin Dimitrov
This is a great answer, can you recommend link/site or book that gives me information in details about WCF or MSDN is sufficient?
Ahmed Said
+1  A: 

But without using DataContract or any attributes, I found the client side working correctly

Yes, that's true - if the data types you use aren't marked with the [DataContract], WCF will try to use the default SOAP serializer on them and just serialize everything that's public (all public properties).

It works - but it might not be what you want / expect - so I'd second darin's opinion - just always use explicit [DataContract] attributes on your types. The clearer you make your intent to yourself (or other programmers who need to maintain your code later), the better. These "magic tricks" that happen behind the scenes tend to cause confusion at times - you're better off not relying on them too much

Marc

marc_s