Q:

DataContract Serialization - Base class property names not working

I have a base class like the following:
[Serializable]
public class SerializableDomainObject<T>
{
    public SerializableDomainObject()
    {
        ID = Guid.NewGuid();
    }

    [DataMember(Name="ID", Order = 0)]
    public Guid ID { get; private set; }

    public void Save()
    {
        // serialize
    }

    public void Load()
    {
        // deserialize
    }
}

I then have lots of derived classes from this, here is an example of one:
[DataContract(Name="MyDomainObject")]
public class MyDomainObject : SerializableDomainObject<MyDomainObject>
{
    public MyDomainObject()
    {
    }

    public MyDomainObject(string name)
    {
        Name = name;
    }

    [DataMember(Order = 1)]
    public string Name { get; private set; }
}

Once serialized here is the output:
<MyDomainObject xmlns="http://schemas.datacontract.org/2004/07/DomainObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <_x003C_ID_x003E_k__BackingField>2b3c00f6-1b15-4a6b-bd6c-a1f447ea5a34</_x003C_ID_x003E_k__BackingField>
    <Name>AName</Name>
</MyDomainObject>

Why is the ID property not being serialized with the name I have provided in the DataMember attribute in the base class?

A:

It is because you have declared that setter for the property as private - since it is private, the DataContractSerializer is serializing the backing field and using its name rather then the property.
The DataContractSerializer will happily serialize any members that you ask it to but with respect to the semantics of the language.  It is usually best to declare your data contracts simply and without a lot of visibility control like this because the message contract between a service and a client should be straightforward and easy to consume.  Create open and unrestricted data contracts but lock down your operation contracts.

