public class SpecialObject { public string ID; [JsonIgnore] public List<SpecialObject> SpecialObjectCollection = new List<SpecialObject>(); [JsonIgnore] public List<string> tempObjectIDs = new List<string>(); [JsonProperty] public List<string> SpecialObjectIDs { get { return SpecialObjectCollection.Select(x => x.ID).ToList(); } set { tempObjectIDs = value; } } public SpecialObject() { } public SpecialObject(string _id) { ID = _id; } } static void Main(string[] args) { SpecialObject parent = new SpecialObject("parentIDstring"); parent.SpecialObjectCollection.Add(new SpecialObject("childIDstring")); string test = JsonConvert.SerializeObject(parent); SpecialObject reconstructedObject = JsonConvert.DeserializeObject<SpecialObject>(test); } //string test: //{"ID":"parentIDstring","SpecialObjectIDs":["childIDstring"]}
我想将SpecialObject序列化为JSON,然后再次返回。“ SpecialObjectIDs”访问器使我避免了讨厌的循环引用,并且因为我只需要唯一的ID,就可以帮助我重建复杂的关系网络。
它可以很好地序列化,但是我需要反序列化对象;当我这样做时,我的数组(JSON中的SpecialObjectIDs)在转换期间就消失了,似乎没有调用set访问器。
如何获取Newtonsoft.Json(JSON.net)库以将反序列化的列表放入tempObjectID中,但保留现有的get行为?
您的问题是,当反序列化非只读的集合时,Json.NET会检查该集合是否已被分配,例如在包含类型的构造函数中。如果是这样,它将为反序列化的JSON内容填充先前存在的集合,而永不回退该集合。不幸的是,您的属性返回了一个临时代理集合,因此您的容器类SpecialObject永远不会收到反序列化的结果。
SpecialObject
JsonPropertyAttribute
ObjectCreationHandling.Replace`](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_ObjectCreationHandling.htm)
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] public List<string> SpecialObjectIDs { get { return SpecialObjectCollection.Select(x => x.ID).ToList(); } set { tempObjectIDs = value; } }
或者,您可以对代理集合属性使用string []而不是List<string>:
string []
List<string>
public string [] SpecialObjectIDs { get { return SpecialObjectCollection.Select(x => x.ID).ToArray(); } set { tempObjectIDs = value == null ? null : value.ToList(); } }
由于无法调整数组大小,因此Json.NET将始终在反序列化时分配一个新数组,并在完成后将其重新设置。