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

25

我正在尝试使用新的StackOverflow API玩耍。不幸的是,我的JSON不够强大,所以我需要一些帮助。

我正试图反序列化这个用户的JSON:

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

将一个我用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; }

    ...
}

我得到了以下异常:

Newtonsoft.Json.JsonSerializationException: 在JSON中未找到所需属性'user_id'。

这是因为JSON对象是一个数组吗?如果是,那么我该如何将其反序列化为一个User对象?

谢谢提前!


4
这个 JSON 中有两个对象。外部对象只有一个属性 user,里面包含了实际的用户对象。你的代码考虑到这一点了吗?我也没有看到任何 JSON 数组。 - Alex Jasmin
3个回答

36

如果你不想创建一个包装类,你也可以通过以下方式访问用户:

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

有关详细信息,请参阅Json.NET文档中的此页面


谢谢!用于反序列化我的对象数组 List<User> deserializedUsers = JsonConvert.DeserializeObject<List<User>>(users.ToString()); - Homer
谢谢!这让我解决了我的问题。 - Bill N.

27

正如Alexandre Jasmin在你的问题评论中所说,生成的JSON包装了你要反序列化的实际User对象。

一个解决方法是创建该包装类:

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

然后反序列化就会起作用:

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

这个包装器将来可能会有其他元数据属性,例如响应时间戳,因此使用它并不是一个坏主意!


非常感谢您的解释和出色的解决方案,Jarrod! - Igal Tabachnik

5
与 @Alexandre Jasmin 的 答案 类似,您可以使用中介的 JsonSerializer 进行转换,而不是使用高级的 JsonConvert.ToString() 上操作。不知道它是否更有效率... 参考:

例子:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接