我从Json.net反序列化对象时不设置访问器 [英] Set accessor not being called when I deserialise object from Json.net

查看:118
本文介绍了我从Json.net反序列化对象时不设置访问器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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,就可以帮助我重建复杂的关系网络.

I want to serialise SpecialObject to JSON and back again. The "SpecialObjectIDs" accessor lets me avoid nasty circular references and helps me reconstruct the complex relational network since I only need the unique IDs.

它可以很好地序列化,但是我需要反序列化对象;当我这样做时,我的数组(JSON中的SpecialObjectIDs)在转换过程中就消失了,似乎没有调用set访问器.

It serialises just fine, but I need to deserialise the objects; when I do so, my array (SpecialObjectIDs in JSON) just disappears during the conversion, the set accessor doesnt seem to be called.

如何获取Newtonsoft.Json(JSON.net)库以将反序列化的List放入tempObjectID中,但保留现有的get行为?

How do I get the Newtonsoft.Json (JSON.net) library to put the deserialised List in tempObjectIDs but keep the existing get behavior?

推荐答案

您的问题是,当对非只读的集合进行反序列化时,Json.NET会检查该集合是否已被分配,例如包含类型的构造函数.如果是这样,它将为反序列化的JSON内容填充先前存在的集合,并且永远不会将集合回退.不幸的是,您的属性返回了一个临时代理集合,因此您的容器类SpecialObject永远不会收到反序列化的结果.

Your problem is that, when deserializing a collection that is not read-only, Json.NET checks to see if the collection has already been allocated, for instance in the constructor of the containing type. If so, it fills the pre-existing collection for the deserialized JSON contents, and never sets the collection back. Unfortunately, your property returns a temporary proxy collection, so your container class SpecialObject never receives the deserialized results.

防止这种情况的最简单方法是,通过

The simplest way to prevent this is to specify that Json.NET should always allocate a new collection and set it back rather than reuse the pre-existing collection, via the JsonPropertyAttribute setting ObjectCreationHandling = ObjectCreationHandling.Replace

[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> SpecialObjectIDs { get { return SpecialObjectCollection.Select(x => x.ID).ToList(); } set { tempObjectIDs = value; } }

或者,您可以使用string []而不是List<string>作为代理集合属性:

Alternatively you could use a string [] rather than a List<string> for your proxy collection property:

public string [] SpecialObjectIDs { get { return SpecialObjectCollection.Select(x => x.ID).ToArray(); } set { tempObjectIDs = value == null ? null : value.ToList(); } }

由于无法调整数组大小,因此Json.NET将在反序列化时始终分配一个新数组,并在完成后将其重新设置.

As arrays cannot be resized, Json.NET will always allocate a new array when deserializing and set it back when complete.

这篇关于我从Json.net反序列化对象时不设置访问器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆