TL;DR; Is there a library or protocol that allows me to serialize some data from a .NET app and deserialize on WP, Win8, iOS and Android while preserving references between objects as they were in code i.e. if a single instance X is a member of Y and Z when Y and Z are deserialized there should be only one X object.
Detailed version:
I want to be able to serialize some objects of types A and B where A has a member of type B and one instance of B can be a member of many instances of A. I should be able to deserialize on WP, Win8, iOS and Android and the same relations should be kept when the data is deserialized. Sadly I cannot test on Android and iOS right now.
The requirements for the serialization mechanism
- Preserve object references when deserializing
- The overhead of the serialization is not really important because the device will get new data like once in three months
- while the overhead is not important it is important that references to the same object are not serialized more once because this can result in very large serialized data.
- be able to serialize with .NET. Serializing on other platforms is not required.
- be able to deserialize on WP, Win8, iOS, Android
[DataContract(IsReference = true)]
public class A
{
[DataMember]
public string Name { get; set; }
[DataMember]
public B MemberB { get; set; }
}
[DataContract(IsReference = true)]
public class B
{
[DataMember]
public string Name { get; set; }
}
Example object graph:
var b1 = new B { Name = "B1" };
var aa = new List { new A { MemberB = b1, Name = "A1" }, new A { MemberB = b1, Name = "A2" } };
I have tried using DataContract Serialization and adding IsReference = true to the DataContract attribute. This works like a charm between desktop .NET and WP and I assume it will work on Windows 8 but I could not even find a way to deserialize DataContractSerialization on iOS and Android without writing my own deserializer let alone out of the box support for preserving references. DataContract serialization will be perfect for me if there is a library that provides deserialization on iOS and Android without additional effort.
I also experimented with an OData service. OData has client libraries for iOS and Android but does it work as expected. It seems like if there is a PK on the entity references will be preserved. I tested on WP and .NET console app like this:
DemoService service = new DemoService(new Uri("http://services.odata.org/OData/OData.svc/"));
var productsQuery = (DataServiceQuery<Product>)
(from p in service.Products.Expand("Category")
where p.Category.ID == 1
select p);
productsQuery.BeginExecute(
(result) =>
{
var actualProducts = productsQuery.EndExecute(result).ToList();
System.Diagnostics.Debug.WriteLine(actualProducts[2].Category == actualProducts[4].Category); //outputs true because both categories are the same
},
null);
It seems it works but am I doing the testing right and does it work like this with iOS and Android clients? I would like to avoid OData because it seems too heavy for my case.
I realize I can give each object an ID and only use the IDs to model the object graph but I am hoping for a cleaner solution. I also want to avoid writing my own serialization code.
Subquestions:
- Is there a way to deserialize DataContract Serialization on iOS and Android without writing my own deserializer
- Does the OData clients for iOS and Android preserve object references? Are they easy to work with
- Do Mono for iOS and Mono for Android suppord DataContract deserialization while preserving object references?
Thanks for your time.