【问题标题】:Json.net JsonIgnore doesn't work for nested classesJson.net JsonIgnore 不适用于嵌套类
【发布时间】:2018-02-06 13:27:03
【问题描述】:

我正在尝试使用 Json.net 序列化一些第三方 json,但问题是他们开始将 Id 作为 Guid 的字符串发送。所以我试图忽略序列化中的 Id,但嵌套属性中似乎存在 JsonIgnore 不起作用的问题。出于这个原因,我决定在之后添加我自己的 Id,但序列化本身似乎并没有忽略我的需要。

我用于序列化的类:

public class ItemA: General.Common
{
    [JsonIgnore]
    public new Guid Id { get; set; } //hiding Guid Id Common
    public Folder ParentFolder { get; set; }
    //...
}

public class Folder
{
    public string Id { get; set; }

    public string Path { get; set; }
}

public class ItemB: NotImportant
{
    //...
    public List<Folder> Folders { get; set; } = new List<Folder>();
    public List<ItemA> ItemAs{ get; set; } = new List<ItemA>();
}

我的代码:

        var jsonSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };

        string json = "some Json-that includes some Ids as strings";
        dynamic d = JsonConvert.DeserializeObject<ItemB>(json, jsonSettings);
        //serialization error here that cannot convert string to Guid in ItemAs 
        ((ItemB)d).ItemAs.ForEach(x => x.Id = new Guid());

编辑: 错误是这样的:

Error converting value "RgAAAAAD01CCe0GCRpDdKTQq2OCQBwAIuTruAfDrRZi9RPZnww3OAAAAAAEMAAAIuTruAfDrRZi9RPZnww3OAABE1hqaAAAA" to type 'System.Guid'...

【问题讨论】:

  • JsonIgnore 跳过序列化,而不是反序列化。
  • Json 中的所有内容是否都表示为字符串,包括 GUID
  • @VidmantasBlazevicius 是的,但不是每个字符串都可以反序列化为 guid
  • 我认为这是类型转换错误,而不是序列化错误。将new Guid() 更改为new Guid().ToString()
  • new Guid() 生成一个“空的”全 0 guid (00000000-0000-0000-0000-000000000000 ),其中 Guid.NewGuid() 生成一个具有唯一值的实际 guid

标签: c# json json.net


【解决方案1】:

有一个官方问题:

Issue #463 - JsonIgnore attribute on shadowed properties

它们是独立的属性,其中一个恰好隐藏了另一个。通过忽略 Derived 上的那个,base 上的属性不再隐藏,而是被序列化。如果您想忽略两者,则将 [JsonIgnore] 放置在两者上,或者如果您希望 Derived 类上的 [JsonIgnore] 忽略两者,则基于属性 virtual 并在 Derived 上覆盖它。 - JamesNK

【讨论】:

    【解决方案2】:

    在反序列化期间可以忽略:基于您的代码的完整工作示例:(请参阅Ignore a property when deserializing using Json.Net with ItemRequired = Required.Always

    using System;
    using System.IO;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    [JsonObject(ItemRequired = Required.Always)]
    public class ItemA : General.Common
    {
        [JsonIgnore]
        [JsonProperty(Required = Required.Default)]
        public new Guid Id { get; set; } //hiding Guid Id Common
        public Folder ParentFolder { get; set; }
        //...
    }
    
    public class Folder
    {
        public string Id { get; set; }
    
        public string Path { get; set; }
    }
    
    public class ItemB : NotImportant
    {
        //...
        public List<Folder> Folders { get; set; } = new List<Folder>();
        public List<ItemA> ItemAs { get; set; } = new List<ItemA>();
    }
    public class Test
    {
    
    
    
        var jsonSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
       //ItemB b = new ItemB()
        //{
        //    Folders = new List<Folder>() {
        //        new Folder() { Id = "1", Path = "myPath1" },
        //        new Folder() { Id = "2", Path = "myPath2" },
        //        new Folder() { Id = "3", Path = "myPath3" } },
        //    ItemAs = new List<ItemA>() {
        //        new ItemA() { Id = Guid.NewGuid(), ParentFolder = new Folder()
        //        { Id = "p1", Path = "parentpath1" } },
        //new ItemA()
        //{ Id = Guid.NewGuid(),
        //    ParentFolder = new Folder()
        //{ Id = "p2", Path = "parentpath2" } }}
        //};
        //string json = JsonConvert.SerializeObject(b);
        string json = "{\"Folders\":[{\"Id\":\"1\",\"Path\":\"myPath1\"},{\"Id\":\"2\",\"Path\":\"myPath2\"},{\"Id\":\"3\",\"Path\":\"myPath3\"}],\"ItemAs\":[{\"Id\":\"RgAAAAAD01CCe0GCRpDdKTQq2OCQBwAIuTruAfDrRZi9RPZnww3OAAAAAAEMAAAIuTruAfDrRZi9RPZnww3OAABE1hqaAAAA\",\"ParentFolder\":{\"Id\":\"p1\",\"Path\":\"parentpath1\"}},{\"Id\":\"c0af33a9-3e6f-4405-a2d4-ff469cb67fce\",\"ParentFolder\":{\"Id\":\"p2\",\"Path\":\"parentpath2\"}}]}";
        dynamic d = JsonConvert.DeserializeObject<ItemB>(json, jsonSettings);
        //no serialization error 
        ((ItemB)d).ItemAs.ForEach(x => x.Id = Guid.NewGuid());
    
    }
    

    【讨论】:

    • 在您的示例中b 是什么?
    • b 用于生成 json 字符串,然后我将其更改为插入错误的 guid“RgAAAAAD01CCe0GCRpDdKTQq2OCQBwAIuTruAfDrRZi9RPZnww3OAAAAAAAEMAAAAIuTruAfDrRZi9RPZnww3OAABE1hqaAAAA”。我已经更新了我的代码以评论它
    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多