使用EKEvents将列表序列化为Xamarin.iOS中的JSON

时间:2016-04-19 11:48:32

标签: c# json serialization xamarin xamarin.ios

当我尝试序列化存储EKEvent的简单List时。我收到这个错误:

  

Newtonsoft.Json.JsonSerializationException:自引用循环   检测到财产' Self'使用类型' Foundation.NSDate'。路径   ' [0] .EndDate&#39 ;.         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference   (Newtonsoft.Json.JsonWriter编写器,System.Object值,   Newtonsoft.Json.Serialization.JsonProperty属性,   Newtonsoft.Json.Serialization.JsonContract合同,   Newtonsoft.Json.Serialization.JsonContainerContract containerContract,   Newtonsoft.Json.Serialization.JsonProperty containerProperty)   [0x00105] in:0         在Newtonsoft.Json.Serialization.JsonSerializerInternalWriter。 CalculatePropertyValues(Newtonsoft.Json.JsonWriter writer,   System.Object值,   Newtonsoft.Json.Serialization.JsonContainerContract合同,   Newtonsoft.Json.Serialization.JsonProperty成员,   Newtonsoft.Json.Serialization.JsonProperty属性,   Newtonsoft.Json.Serialization.JsonContract&安培; memberContract,   System.Object的&安培; memberValue)[0x000c7] in:0         在Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject   (Newtonsoft.Json.JsonWriter编写器,System.Object值,   Newtonsoft.Json.Serialization.JsonObjectContract合约,   Newtonsoft.Json.Serialization.JsonProperty成员,   Newtonsoft.Json.Serialization.JsonContainerContract   collectionContract,Newtonsoft.Json.Serialization.JsonProperty   containerProperty)[0x0003c] in:0

当我尝试使用JsonConvert.SerializeObject方法时会发生这种情况。 序列化EKEvent列表的任何解决方法?

修改

使用JsonSerializerSettings有效!

但是,当我尝试反序列化对象时,我遇到了另一个问题:

Newtonsoft.Json.JsonSerializationException:无法找到用于EventKit.EKEvent类型的构造函数。 @ 一个类应该有一个默认的构造函数,  一个带参数的构造函数或一个用JsonConstructor属性标记的构造函数。  路径' [0] .ClassHandle',第1行,第16位。   在Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject    (Newtonsoft.Json.JsonReader reader,Newtonsoft.Json.Serialization.JsonObjectContract objectContract,    Newtonsoft.Json.Serialization.JsonProperty containerMember,    Newtonsoft.Json.Serialization.JsonProperty containerProperty,    System.String id,System.Boolean& createdFromNonDefaultCreator)[0x000d6] in:0   在Newtonsoft.Json.Serialization.JsonSerializerInternalReader。   CreateObject(Newtonsoft.Json.JsonReader reader,System.Type objectType,Newtonsoft.Json.Serialization.JsonContract contract,Newtonsoft.Json.Serialization.JsonProperty member,Newtonsoft.Json.Serialization.JsonContainerContract containerContract,Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue)[0x0013b] in:0   在Newtonsoft.Json.Serialization.JsonSerializerInternalReader。   CreateValueInternal(Newtonsoft.Json.JsonReader reader,System.Type objectType   ,Newtonsoft.Json.Serialization.JsonContract合约,Newtonsoft.Json.Serialization.JsonProperty成员,   Newtonsoft.Json.Serialization.JsonContainerContract containerContract,Newtonsoft.Json.Serialization.JsonProperty containerMember,System.Object existingValue)[0x0006d] in:0   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list,   Newtonsoft.Json.JsonReader阅读器,Newtonsoft.Json.Serialization.JsonArrayContract合同,    Newtonsoft.Json.Serialization.JsonProperty containerProperty,System.String id)[0x000cb] in:0

2 个答案:

答案 0 :(得分:2)

Giorgi的回答回答了关于如何序列化数据的问题的第一部分,您似乎已经解决了这个问题。但是,现在再次对其进行反序列化会出现问题。

查看您在开场帖中提供的堆栈跟踪,其中显示:

  

无法找到用于EventKit.EKEvent类型的构造函数。 @一个类应该有一个默认的构造函数,一个带参数的构造函数或一个用JsonConstructor属性标记的构造函数

特别说明了这个错误。现在,查看EventKit EKEvent API reference,我们发现以下内容:

  1. 所有构造函数都标记为protected
  2. 没有不带参数的构造函数
  3. 这意味着,当DeserializeObject方法尝试创建EKEvent实例时,它没有任何方法可以这样做。它不知道提供什么参数。

    EKEvent类还存在其他问题。即使它有没有参数的公共构造函数。它拥有的所有属性都标记为read-only。这意味着再次反序列化序列化程序时,无法使用序列化事件填充属性。

    所以你有两个选择:

    1. 创建一个包装EKEvent的类或模仿EKEvent并反序列化为
    2. 使用提供的EKEventStore来保留EKEvents。 As the API docs describe:“EventStore需要在EventKit中执行任何操作。它可以被认为是所有EventKit数据的持久存储或数据库引擎。”
    3. 开场文没有描述为什么要序列化和反序列化此对象的原因。但是,如果您想将其与某些API进行通信,我建议您选择1,因为它不是特定于平台的,您可以将其设置为只在App和API之间传递相关数据,从而节省宝贵的带宽。

答案 1 :(得分:1)

您收到错误,因为EKEvent对其属性具有递归引用。您可以使用 ReferenceLoopHandling 设置指定json序列化程序应忽略自引用循环:

JsonConvert.SerializeObject(myList, new JsonSerializerSettings
                            { 
                                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                            });

您还可以全局设置序列化程序设置,这样就不必为每次调用指定它:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

您可以在Json.NET文档中看到完整的示例:http://www.newtonsoft.com/json/help/html/ReferenceLoopHandlingIgnore.htm