25

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!

1
  • 4
    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. Commented Mar 31, 2010 at 18:43

3 Answers 3

36

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Used to deserialize my array of objects List<User> deserializedUsers = JsonConvert.DeserializeObject<List<User>>(users.ToString());
Thanks! This led me to fixing my issue
27

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!

1 Comment

Thank you very much, Jarrod, for the explanation, and the very great solution!
5

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());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.