Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing json to C# list with existing items

Tags:

json

c#

json.net

Given the following classes:

class Report {

    public Report() {
        this.Fields=new List<Field>();
    }

    [JsonProperty("fields")]
    public IList<Field> Fields { get; private set; }
}

class Field {

    [JsonProperty("identifier")]
    public Guid Identfier { get;set; }

    [JsonProperty("name")]
    public string Name { get;set; }
}

and the following test method set up:

var report = new Report();
report.Fields.Add(new Field { Identifier = new Guid("26a94eab-3d50-4330-8203-e7750abaa060"), Name = "Field 1" });
report.Fields.Add(new Field { Identifier = new Guid("852107db-b5d1-4344-9f71-7bd90b96fec0"), Name = "Field 2" });

var json = "{\"fields\":[{\"identifier\":\"852107db-b5d1-4344-9f71-7bd90b96fec0\",\"name\":\"name changed\"},{\"identifier\":\"ac424aff-22b5-4bf3-8232-031eb060f7c2\",\"name\":\"new field\"}]}";

JsonConvert.PopulateObject(json, report);

Assert.IsTrue(report.Fields.Count == 2, "The number of fields was incorrect.");

How do I get JSON.Net to know that the field with identifier "852107db-b5d1-4344-9f71-7bd90b96fec0" should apply to the existing field with the same identifier?

Also, is it possible to get JSON.Net to remove items that do not exist within the given JSON array, (specifically the field with identifier "26a94eab-3d50-4330-8203-e7750abaa060" should be removed because it does not exist in the given json array.

If there is a way to manually code or override the way that JSON analyses a list then that would be better because I could write the code to say "this is the item you need" or "use this newly created item" or just "don't do anything to this item because I have removed it". Anyone know of a way I can do this please?

like image 415
Anupheaus Avatar asked Feb 09 '23 18:02

Anupheaus


1 Answers

You can use the option ObjectCreationHandling = ObjectCreationHandling.Replace.

You can do this for your entire data model using serializer settings, as is shown in Json.Net PopulateObject Appending list rather than setting value:

    var serializerSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
    JsonConvert.PopulateObject(json, report, serializerSettings);

Or, you can set the option on the JsonProperty attribute you are already using if you don't want to do this universally:

class Report
{
    public Report()
    {
        this.Fields = new List<Field>();
    }

    [JsonProperty("fields", ObjectCreationHandling = ObjectCreationHandling.Replace)]
    public IList<Field> Fields { get; private set; }
}
like image 160
dbc Avatar answered Feb 19 '23 11:02

dbc