如何在.NET上序列化,在WP、Win8、iOS和Android上反序列化,并保留引用



TL;DR;有没有一个库或协议允许我序列化.NET应用程序中的一些数据,并在WP、Win8、iOS和Android上进行反序列化,同时保留对象之间的引用,就像它们在代码中一样,即如果单个实例X是Y和Z的成员,当Y和Z被反序列化时,应该只有一个X对象。

详细版本:

我希望能够序列化A和B类型的一些对象,其中A有一个B类型的成员,B的一个实例可以是A的许多实例的成员。我应该能够在WP、Win8、iOS和Android上进行反序列化,并且在反序列化数据时应该保持相同的关系。遗憾的是,我现在无法在Android和iOS上进行测试。

序列化机制的要求

  • 反序列化时保留对象引用
  • 序列化的开销其实并不重要,因为设备会像三个月一次那样获得新数据
  • 虽然开销并不重要,但对同一对象的引用不要再序列化一次是很重要的,因为这可能会导致非常大的序列化数据
  • 能够使用.NET进行序列化。不需要在其他平台上进行序列化
  • 能够在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" } };

我尝试过使用DataContract序列化并将IsReference=true添加到DataContract属性中。这在桌面.NET和WP之间很有魅力,我认为它会在Windows 8上运行,但如果不编写自己的反序列化程序,我甚至找不到在iOS和Android上反序列化DataContractSerialization的方法,更不用说对保留引用的开箱即用支持了。如果有一个库可以在iOS和Android上提供反序列化,而不需要额外的努力,那么DataContract序列化对我来说将是完美的。

我还试用了OData服务。OData有适用于iOS和Android的客户端库,但它能按预期工作。似乎如果实体上有PK,则引用将被保留。我在WP和.NET控制台应用程序上测试了如下:

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);

它似乎有效,但我的测试做得对吗?它在iOS和Android客户端上这样有效吗?我想避开OData,因为它对我的案子来说太重了。

我意识到我可以给每个对象一个ID,只使用这些ID来建模对象图,但我希望有一个更干净的解决方案。我还希望避免编写自己的序列化代码。

子问题:

  1. 有没有一种方法可以在iOS和Android上反序列化DataContract序列化,而无需编写自己的反序列化程序
  2. iOS和Android的OData客户端是否保留对象引用?他们容易相处吗
  3. iOS版Mono和Android版Mono在保留对象引用的同时支持DataContract反序列化吗

谢谢你抽出时间。

我会使用谷歌的协议缓冲区。其他语言还有其他实现,包括Objective C和C#。

更新:

如果我在做这件事,我会从在任何地方使用.NET开始,包括在Android上(通过使用MonoDroid)和(在iOS上使用MonoTouch)。是的,您现在可以在任何平台上共享C#代码!

我希望序列化的每个对象都有一个等价的对象,定义为Protocol Buffer对象。每个对象都有一个序列化的哈希值作为其ID。对象中的每个引用都将被定义为一个哈希值。

然后,在每个对象中都有一些代码来遍历下面的对象,并在执行过程中序列化到协议缓冲区对象。填充哈希值引用。

每个对象引用都会被查找并存储在对象的字典(哈希值/地址)中(如果不存在的话)。这也是序列化的。这将停止序列化对象两次,因为在整个操作中对象只序列化/取消序列化一次。这是通过设置/清除字典中对象的地址来完成的。

我以前写过这些东西,没什么大不了的。

最新更新