c# - 当我从 Json.net 反序列化对象时设置访问器不被调用

标签 c# json serialization json.net accessor

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) 库将反序列化列表放入 tempObjectIDs 但保持现有的获取行为?

最佳答案

你的问题是,当反序列化一个非只读的集合时,Json.NET 检查集合是否已经分配,​​例如在包含类型的构造函数中。如果是这样,它会为反序列化的 JSON 内容填充预先存在的集合,并且永远不会设置回集合。不幸的是,你的属性(property)返回一个临时代理集合,所以你的容器类 SpecialObject永远不会收到反序列化的结果。

防止这种情况的最简单方法是通过 JsonPropertyAttribute 指定 Json.NET 应始终分配一个新集合并将其设置回去,而不是重用预先存在的集合。设置 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>对于您的代理集合属性:

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

由于数组无法调整大小,Json.NET 总是会在反序列化时分配一个新数组,并在完成时将其重新设置。

关于c# - 当我从 Json.net 反序列化对象时设置访问器不被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33608226/

相关文章:

c# - 'Press Any key to continue.... '的解释

c# - 使用反射在嵌套对象中设置属性

jquery - Bower.json : main is present but I get a "(...) is missing "main"entry in bower. json“警告

java - 数独游戏序列化问题

java - 如何将对象二进制(反)序列化为/形成字符串?

c# - COM Interop,RPC 服务器在 c# 中不可用

java - 如何将 2 个 json 合并为一个来解析 JSON

json - 已导入包但未在 JSON 解析器中使用

c# - 强制 JSON.NET 在序列化 DateTime 时包含毫秒(即使 ms 组件为零)

c# - 在 C# 中修改数组 "in-place"?