views:

323

answers:

2

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"&gt;
    <_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?

+2  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.

Andrew Hare
Is there any way to keep this property private and specify a name? Or does it only ever work with Public properties? Reason for this is because I don't really want to allow the users to edit the ID field.
James
If you really want to keep it private with a name you define then explicitly declare a backing field and don't use C#'s automatically implemented properties.
Andrew Hare
Thanks using a private field did the trick.
James
A: 

Can you try changing your private declaration to internal? Would that still achieve your visibility needs? I have that on my contracts and things serialize/deserialize quite nicely.

Ben Runchey
@Ben nope doesn't seem to work using internal setter.
James