views:

507

answers:

2

based on my understanding WCF's data contract model was opt-in vs the old opt-out approach of asmx web-services. you have to explicitly include all the fields and types that you require using DataContractAttribute and DataMemberAttribute. my experience however has been different.

take a look at the following examples,


///CASE: 1
///Behaves as excpected BoolValue is included but String Value is emitted
[DataContract]
public class CompositeType
{
    [DataMember]
    public bool BoolValue { get; set; }

    public string StringValue { get; set; }
}


///CASE: 2
///All elements are included, as if everything was marked.
public class CompositeType
{
   public bool BoolValue { get; set; }

    public string StringValue { get; set; }
}


///CASE: 3
/// MyEnum Type is included even though the MyEnum is not marked.
[DataContract]
public class CompositeType
{
    [DataMember]
    public bool BoolValue { get; set; }

    [DataMember]
    public string StringValue { get; set; }

    [DataMember]
    public MyEnum EnumValue{ get; set; }
}

public enum MyEnum
{
    hello = 0,
    bye = 1
}


///CASE: 4
/// MyEnum Type is no longer included. EnumValue is serialized as a string
[DataContract]
public class CompositeType
{
    [DataMember]
    public bool BoolValue { get; set; }

    [DataMember]
    public string StringValue { get; set; }

    [DataMember]
    public MyEnum EnumValue{ get; set; }
}

[DataContract]
public enum MyEnum
{
    hello = 0,
    bye = 1
}


///CASE: 5
//Both hello and bye are serilized
public enum MyEnum
{
    [EnumMember]
    hello = 0,
    bye = 1
}


///CASE: 6
//only hello is serilized
[DataContract]    
public enum MyEnum
{
    [EnumMember]
    hello = 0,
    bye = 1
}

All I can say is WCF WTF?

+3  A: 

Enumerations are always serializable by definition. When you define a new enum, there is no need to apply the DataContract attribute on it, and you can freely use it in a data contract.If you want to exclude certain enum values from the data contract, you need to first decorate the enum with the DataContract attribute. Then, explicitly apply the EnumMemberAttribute to all enum values you want to include in the enum data contract. Like this

[DataContract]
enum ContactType
{
   [EnumMember]
   Customer,

   [EnumMember]
   Vendor,

   //Will not be part of data contract
   Partner
}

will result in this wire representation:

enum ContactType
{
   Customer,
   Vendor
}

Which is not true for classes, what is explaining the first case, see Programming WCF Services

ArsenMkrt
A: 

Note: I have not worked with WCF & this is purely based on reading.

Case 2: If CompositeType is used as property/field/return value of a service, it will be serialized (as it is public).

Case 3: Same as Case 2. Because the container type is serializable, the enum (although it is not marked) will get serialized.

Case 4: Enum will be serialized as string. You can use Value property when applying EnumMember to change the serialized value.

Case 5: Same as Case 2

Case 6: You are being explicit on Enum & have applied DataContract, DataMember for one of the enum values. Thereby telling serializer to ignore the other member of the enum.

Please don't be critical, as this is purely based on a quick glance understanding of doc reading :)

shahkalpesh