4

I have a class in the format:

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

What i tried to read the JSON from a file:

using (StreamReader r = new StreamReader(path))
{
    string json = r.ReadToEnd();

    //var items = JsonConvert.DeserializeObject<IEnumerable<Person>>(json);
}

When I got the JSON in a string I got that in the format below:

[
    ["John", 30, "BMW"],
    ["Tim", 45, "Ford"],
    ["Kim", 34, "Toyota"]
]

I thought that JSON would be Deserialize in that IEnumerable<Person>, but it couldn't.

What is the correct way to deserialize the JSON string with that Person class?

3

2 Answers 2

2

Since you have only values without properties names in your JSON, you can deserialize it into sequence of collection objects, like IEnumerable<string[]>, IEnumerable<List<string>> or List<List<string>>. Then parse every item to Person manually (assuming that you have the same structure for all items, otherwise you'll need an additional logic for checking an errors)

var result = JsonConvert.DeserializeObject<IEnumerable<string[]>>(jsonString);
var persons = result
    .Select(item => new Person { Name = item[0], Age = int.Parse(item[1]), Car = item[2] })
    .ToList();
Sign up to request clarification or add additional context in comments.

Comments

0

If you want to deserialize into a Person object, then your array items need to be in a key/value object structure instead of an array of strings. Your JSON should be the following:

[
  { 
    name: "John", 
    age: 30, 
    car: "BMW" 
  },
  { 
    name: "Tim", 
    age: 45, 
    car: "Ford" 
  },
  { 
    name: "Kim", 
    age: 34, 
    car: "Toyota" 
  }
]

EDIT: Since you are unable to change the input file structure, I would recommend reading in as an IEnumerable<string[]>.

Then you can proceed to read with the following:

var rawPersons = JsonConvert.Deserialize<IEnumerable<string[]>>(json);

If you create a constructor on your Person class, then it can populate your properties from the raw Person object:

public Person(string[] parts) {
    if(parts.Length != 3) {
        throw new ArgumentException("Not a valid person.");
    }

    Name = parts[0];
    var validAge = int.TryParse(parts[1], out Age);
    if(!validAge) {
      throw new ArgumentException("Age is not an integer.");
    }
    Car = parts[2];
}

Lastly, you can use a projection on your raw persons to get a collection of Person objects.

var persons = rawPersons.Select(p => new Person(p));

7 Comments

Yeah, sorry! that would be perfectly deserialized into Person, but I won't be getting the JSON as a key/value. I must read the JSON file with that format.
Ah, so you would need to use a more custom reading approach for creating Person objects.
hmm...may be a dynamic object? and mapping it manually?
I've added an example of how you could read your input file and project to a list of Person objects.
this seems a good solution let me try in my use case.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.