1

I'm using .NET Framework 4.7.2 with the package Newtonsoft.Json 12.0.3.

I'm trying to de-serialize an incoming JSON string into a List<Person>. When the JSON string is an array of random objects, the result is actually a List<Person> of the same length as the incoming array and each Person seems to have been created with the default constructor!

public class Person
{
    public string Name { get; set; }
    public int? Age { get; set; }
}

De-serialization example:

string json = "[{\"random\": \"stuff\"}, {\"whatever\": 24}]";
var persons = JsonConvert.DeserializeObject<List<Person>>(json);

persons is a list with 2 Person objects that have both Name null and Age null. This seems like really strange default behavior!

I want to throw an error if the incoming array has even a single object that isn't a proper Person. I wan them explicitly to have a Name and an Age, even if they're null. Example: I want "[{"Name": "Bob", "Age":null}]" to become a Person with Name="Bob" and Age equals null. I only care that they explicitly define all the properties.

How can this be done without changing the Person class?

UPDATE: For future reference, the linked questions cover my needs because I want to do both of these things at the same time.

igg
  • 2,172
  • 3
  • 10
  • 33
  • 1
    https://www.newtonsoft.com/json/help/html/DeserializeMissingMemberHandling.htm . (Found by googling "json.net throw if unexpected property", 3rd link) – canton7 Jan 08 '21 at 11:54
  • @canton7 `MissingMemberHandling.Error` is only a partial solution. If I provide `[{"Name":"Bob"}]` that's going to create a `Person`. I want it to throw because `Age` is missing on the original JSON string. – igg Jan 08 '21 at 12:09
  • You are missing an object above person. IMO it tries to convert `{\"random\": \"stuff\"}` and `{\"whatever\": 24}` as both different persons. Could you try something like: `[{ {\"random\": \"stuff\"}, {\"whatever\": 24} }]` ? – Bartosz Olchowik Jan 08 '21 at 12:30
  • @BartoszOlchowik I don't understand your comment. – igg Jan 08 '21 at 12:31
  • @igg you tell deserializer that you have 2 different persons, but you want it to treat it as a one person. you can do it by putting your string into one object, so just add { 'yourjsonstringgoeshere'} – Bartosz Olchowik Jan 08 '21 at 12:32
  • @BartoszOlchowik No, I don't want to treat it as 1 person, it should try to convert each object into a `Person`. I want it to throw errors, because the objects aren't `Person` – igg Jan 08 '21 at 12:37
  • @igg https://stackoverflow.com/questions/26264547/what-exceptions-does-newtonsoft-json-deserializeobject-throw – Bartosz Olchowik Jan 08 '21 at 12:39
  • 1
    @igg Use that in conjunction with https://stackoverflow.com/questions/29655502/json-net-require-all-properties-on-deserialization ? – canton7 Jan 08 '21 at 13:17
  • If your **model** has properties that your **JSON** may lack, and you want that to be an error, see [Json.NET require all properties on deserialization](https://stackoverflow.com/q/29655502/3744182). Conversely if your **JSON** may have properties that your **model** lacks, and you want that to be an error, see [Detect if deserialized object is missing a field with the JsonConvert class in Json.NET](https://stackoverflow.com/q/21030712/3744182). Since you seem to want both, this looks to be a duplicate of both, agree? – dbc Jan 08 '21 at 15:02
  • And if you want to log the errors and continue see [Ignore parsing errors during JSON.NET data parsing](https://stackoverflow.com/a/26108527/3744182) and [What exceptions does Newtonsoft.Json.DeserializeObject throw?](https://stackoverflow.com/q/26264547/3744182). – dbc Jan 08 '21 at 15:09
  • @dbc You are right, I want both. The answers you link cover my needs. Is there a way to mark a question as a duplicate of 2 other questions? – igg Jan 08 '21 at 15:11
  • Yes, I'll do it – canton7 Jan 08 '21 at 15:12

0 Answers0