4
votes

I'm getting some JSON data from the external API. I have my POCO objects to which the data is deserialized. I use System.Text.Json.JsonSerializer for deserialization. Recently, I realized that the structure of the JSON that I receive has changed and I got to know it only by accident while checking something else. My question is, is it possible to catch somehow the json data that didn't succeed to be mapped to any POCO fields?

To be more precise with my question here is an example POCO:

public class Car
{
    public string Name { get; set; }
    public int Age { get; set; }
}

JSON that I received before:

{"Name" : "PinkCar", "Age": 3}

JSON that I receive now:

{"Name" : "PinkCar", "Age": 3, "RogueField": "Loser"}

I would like to be able to at least get somehow information that there is this new "RogueField" that doesn't match any POCO properties without breaking the process of deserialization.

2
You can use JsonExtensionData in JSON.Net if it's an option for you. I can't find anything in the standard serialisation types that suggests you can have a "catch all" event so you can handle unknown or new properties. Example here: newtonsoft.com/json/help/html/DeserializeExtensionData.htmCharleh
How are you deserialising the data? Are you manually doing it or are you relying on MVC model binding? If MVC, which version of .NET Core are you using?DavidG
I'm not aware of any built-in functionality that would help you with that. I guess I would create a simple JsonConverter which can log any properties that doesn't exist on the target object.Mono
@DavidG I do it manually by typing: System.Text.Json.JsonSerializer.Deserialize<Car>(json); @Mono I like your idea, but to be honest I have no clue how to catch these data with a JsonConverter. Isn't it that json converter is only run if there is data in a json that matches a property name? I'm not sure if you know what I mean.LilacBlue

2 Answers

3
votes

Extra properties can be saved in a dictionary with your object. You can manipulate this directory and it will be used when serializing your object again.

From https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#handle-overflow-json: Create a property of the type Dictionary<string, object>, this can have any name (mostly this is named ExtensionData but can be anything), and decorate it with the [JsonExtensionData] attribute, for example:

public class Car
{
    public string Name { get; set; }
    public int Age { get; set; }
    [JsonExtensionData]
    public Dictionary<string, object> ExtensionData { get; set; }
}
2
votes

Unfortunately, at the current time, there is no way to using the System.Text.Json objects that are part of .NET Core. It is currently unsupported.

You can use Newtonsoft JSON though, for example:

var settings = new JsonSerializerSettings
{
    MissingMemberHandling = MissingMemberHandling.Error
};

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Car>(json, settings);

Now when your POCO misses any fields, it will throw a JsonSerializationException:

JsonSerializationException: Could not find member 'RogueField' on object of type 'Car'. Path 'RogueField', line 1, position 44.