简体   繁体   中英

Json.net JsonIgnore doesn't work for nested classes

I am trying to serialize some third party json using Json.net and the problem is that they started sending Ids as strings insted of Guids. So I am trying to ignore the Ids within serialization but there seems to be a problem within nested properties that the JsonIgnore doesn't work. For that reason I decided to add my own Ids after but the serialisation itself doesn't seem to ignore what I need it to.

My classes used for serialization:

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>();
}

My Code:

        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());

EDIT: The error is something like this:

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

There is an official Issue about this:

Issue #463 - JsonIgnore attribute on shadowed properties

They are separate properties, one happens to be hiding the other. By ignoring the one on Derived then the property on base is no longer hidden and is being serialized instead. If you want to ignore both then place [JsonIgnore] on both, or if you want [JsonIgnore] on the Derived class to ignore both then base the property virtual and override it on Derived. - JamesNK

It's possible to ignore during deserialize : fully working example based on your code: (see 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());

}

结果截图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM