views:

59

answers:

2

Having read the documentation and many many articles I believe the following should work but it doesn't.

This is how my datacontracts are structured.

[DataContract]
[KnownType(typeof(Friend))]
public class Person
{
   private string name;

   [DataMember]
   public string Name { get { return name; } set { name = value; }}

   private Place location;

   [DataMember]
   public Place Location { get { return location; } set { location = value; }}
}

[DataContract]
public class Friend : Person
{
   private int mobile;

   [DataMember]
   public int Mobile { get { return mobile; } set { mobile = value; }}
}

[DataContract]
[KnownType(typeof(City))]
public class Place
{
   private int altitude;

   [DataMember]
   public int Altitude { get { return altitude; } set { altitude = value; }}
}

[DataContract]
public class City : Place
{
   private int zipCode;

   [DataMember]
   public int ZipCode { get { return zipCode; } set { zipCode = value; }}
}

The client sends the following example object:

Person tom = new Friend();
tom.Name = "Tom";

Place office = new City();
office.Altitude = 500;
office.ZipCode = 900500;

tom.Location = office;

The issue is for some reason none of the Place values are serialized.

What mistake am I making?

Thanks.

A: 

DataContract uses opt-in, Serializeable uses Opt-out. That is why it works when using Serializeable. You need to mark the backing fields as DataMembers, not the properties:

[DataContract]
[KnownType(typeof(Friend))]
public class Person
{
   [DataMember]
   private string name;

   public string Name { get { return name; } set { name = value; }}

   [DataMember]
   private Place location;

   public Place Location { get { return location; } set { location = value; }}
}

[DataContract]
public class Friend : Person
{
   [DataMember]
   private int mobile;

   public int Mobile { get { return mobile; } set { mobile = value; }}
}

[DataContract]
[KnownType(typeof(City))]
public class Place
{
   [DataMember]
   private int altitude;

   public int Altitude { get { return altitude; } set { altitude = value; }}
}

[DataContract]
public class City : Place
{
   [DataMember]   
   private int zipCode;

   public int ZipCode { get { return zipCode; } set { zipCode = value; }}
}
Flo
1) I have not tried using Serializable, I tested with DataContractSerializer.
mob1lejunkie
2) According to documentation DataMember attribute can be applied to properties so I don't think this is the issue. http://msdn.microsoft.com/en-us/library/ms730167(v=VS.85).aspx
mob1lejunkie
A: 

After much frustration turns out my datacontract design was flawed :(

mob1lejunkie
Care to share the flaw? Several people put time into trying to understand your issue. It would be nice if you would share the root cause now that you found it.
ErnieL
In the actual implementation both Person and Friend had reference to Location. Client was setting properties on Location object in Person but not on Location object on Friend. This was the reason properties of Location object were not serialized.
mob1lejunkie