简体   繁体   English

使用Json.NET将JSON反序列化为对象

[英]Deserializing JSON into an object with Json.NET

I'm playing a little bit with the new StackOverflow API . 我正在使用新的StackOverflow API Unfortunately, my JSON is a bit weak, so I need some help. 不幸的是,我的JSON有点弱,所以我需要一些帮助。

I'm trying to deserialize this JSON of a User: 我正在尝试反序列化用户的这个JSON:

  {"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: 到我用JsonProperty属性修饰的对象:

[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. Newtonsoft.Json.JsonSerializationException:在JSON中找不到必需属性'user_id'。

Is this because the JSON object is an array? 这是因为JSON对象是一个数组吗? If so, how can I deserialize it to the one User object? 如果是这样,我如何将其反序列化为一个User对象?

Thanks in advance! 提前致谢!

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. 有关详细信息,请参阅Json.NET文档中的此页面

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. 正如Alexandre Jasmin在您的问题的评论中所说,生成的JSON包含了您尝试反序列化的实际User对象的包装。

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, eg response timestamp, so it's not a bad idea to use it! 此包装器上将有未来的元数据属性,例如响应时间戳,因此使用它并不是一个坏主意!

Similar to @Alexandre Jasmin's answer , you can use an intermediary JsonSerializer to convert instead of the using the high-level JsonConvert on .ToString() . 与@Alexandre Jasmin的答案类似,您可以使用中间JsonSerializer进行转换,而不是使用.ToString()上的高级JsonConvert 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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM