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

如何在.NET上序列化和在WP、Win8、iOS和Android上反序列化并保留引用,android,ios,serialization,odata,windows-phone,Android,Ios,Serialization,Odata,Windows Phone,TL;博士 是否有一个库或协议允许我序列化.NET应用程序中的一些数据,并在WP、Win8、iOS和Android上反序列化,同时保留对象之间的引用,就像它们在代码中一样,即如果单个实例X是Y和Z的成员,当Y和Z反序列化时,应该只有一个X对象 详细版本: 我希望能够序列化A和B类型的一些对象,其中A有一个B类型的成员,B的一个实例可以是A的多个实例的成员。我应该能够在WP、Win8、iOS和Android上进行反序列化,并且在反序列化数据时应保持相同的关系。遗憾的是,我现在无法在Android和

TL;博士 是否有一个库或协议允许我序列化.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添加到DataContract属性。这就像是desktop.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);
DemoService服务=新的DemoService(新的Uri(“http://services.odata.org/OData/OData.svc/"));
var productsQuery=(DataServiceQuery)
(来自p in service.Products.Expand(“类别”)
其中p.Category.ID==1
选择p);
productsQuery.BeginExecute(
(结果)=>
{
var actualProducts=productsQuery.EndExecute(result.ToList();
System.Diagnostics.Debug.WriteLine(actualProducts[2].Category==actualProducts[4].Category);//输出为true,因为两个类别相同
},
无效);
它似乎可以工作,但我做的测试是正确的吗?它在iOS和安卓客户端上是否也可以这样工作?我想避开OData,因为它对我的箱子来说太重了

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

子问题:

  • 有没有一种方法可以在iOS和Android上反序列化DataContract序列化,而不用编写自己的反序列化程序
  • iOS和Android的OData客户端是否保留对象引用?他们容易相处吗
  • Mono for iOS和Mono for Android是否在保留对象引用的同时支持DataContract反序列化
  • 谢谢你的时间。

    我会用谷歌的。还有其他语言的实现,包括Objective C和C#

    更新:

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

    我希望序列化的每个对象都将有一个等效对象定义为协议缓冲区对象。每个对象都有一个序列化的哈希值作为其ID。对象中的每个引用都将定义为哈希值

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

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


    我以前写过这篇文章,但没什么大不了的。

    根据这次讨论,协议缓冲区似乎没有提供保存引用的选项:据我所知,消息的大小是协议缓冲区的主要优点,因为我并不真正关心消息的大小,所以我宁愿使用更普遍的东西类似于JSOn或XML。两者都不维护对象引用。:-)Python的泡菜怎么样?:-)它不难,紧凑,并且可以处理对象引用。您可能需要自己实现它-我认为这不是您想要做的。使用Python序列化在.NET中进行序列化,并在Java和Objective-C中对其进行反序列化?:)某些版本的协议缓冲区确实维护对象图。。。见:@AnthonyLambert有趣。问题仍然与其他选择相同。我可以用.NET像这样序列化,并在WP、Win8、Android和iOS上反序列化吗。只支持一个库是不够的。编辑:我回复的评论现在不见了。JSON本身不提供任何以类似图形的方式保留对象引用的方法。它只提供了保存对象树的方法。我很乐意使用能够保留对象引用的JSON序列化程序。序列化程序通过为每个对象分配一个ID并在对象再次序列化时引用该ID来实现这一点。反序列化时,反序列化程序存储已反序列化的
    
    var b1 = new B { Name = "B1" };
    var aa = new List { new A { MemberB = b1, Name = "A1" }, new A { MemberB = b1, Name = "A2" } };
    
    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);