Deserializing JSON into an object with Json.NET

52,870

Solution 1

As Alexandre Jasmin said in the comments of your question, the resulting JSON has a wrapper around the actual User object you're trying to deserialize.

A work-around would be having said wrapper class:

public class UserResults
{
    public User user { get; set; }
}

Then the deserialization will work:

using (var sr = new StringReader(json))
using (var jr = new JsonTextReader(sr))
{
    var js = new JsonSerializer();
    var u = js.Deserialize<UserResults>(jr);
    Console.WriteLine(u.user.display_name);
}

There will be future metadata properties on this wrapper, e.g. response timestamp, so it's not a bad idea to use it!

Solution 2

If you don't want to create a wrapper class you can also access the User this way:

String jsonString = "{\"user\":{\"user_id\": 1, \"user_type\": \"moderat...";
JToken root = JObject.Parse(jsonString);
JToken user = root["user"];
User deserializedUser = JsonConvert.DeserializeObject<User>(user.ToString());

See this page in the Json.NET doc for details.

Solution 3

Similar to @Alexandre Jasmin's answer, you can use an intermediary JsonSerializer to convert instead of the using the high-level JsonConvert on .ToString(). No idea if it's any more efficient...

References:

Example:

var root = JObject.Parse(jsonString);
var serializer = new JsonSerializer();
var expectedUserObject = serializer.Deserialize<User>(root["user"].CreateReader());
Share:
52,870

Related videos on Youtube

ShockwaveNN
Author by

ShockwaveNN

Updated on July 09, 2022

Comments

  • ShockwaveNN
    ShockwaveNN almost 2 years

    I'm playing a little bit with the new StackOverflow API. Unfortunately, my JSON is a bit weak, so I need some help.

    I'm trying to deserialize this JSON of a User:

      {"user":{
        "user_id": 1,
        "user_type": "moderator",
        "creation_date": 1217514151,
        "display_name": "Jeff Atwood",
        ...
        "accept_rate": 100
      }}
    

    into an object which I've decorated with JsonProperty attributes:

    [JsonObject(MemberSerialization.OptIn)]
    public class User
    {
        [JsonProperty("user_id", Required = Required.Always)]        
        public virtual long UserId { get; set; }
    
        [JsonProperty("display_name", Required = Required.Always)]
        public virtual string Name { get; set; }
    
        ...
    }
    

    I get the following exception:

    Newtonsoft.Json.JsonSerializationException: Required property 'user_id' not found in JSON.

    Is this because the JSON object is an array? If so, how can I deserialize it to the one User object?

    Thanks in advance!

    • Alex Jasmin
      Alex Jasmin about 14 years
      You have two objects in this JSON. The outer object has a single property user which contains the actual user object. Are you taking this into account in your code? I also don't see any JSON arrays here.
  • ShockwaveNN
    ShockwaveNN about 14 years
    Thank you very much, Jarrod, for the explanation, and the very great solution!
  • Homer
    Homer about 11 years
    Thanks! Used to deserialize my array of objects List<User> deserializedUsers = JsonConvert.DeserializeObject<List<User>>(users.ToString());
  • Bill N.
    Bill N. almost 6 years
    Thanks! This led me to fixing my issue