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

3 回答 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 文档中的此页面

于 2010-03-31T19:31:40.483 回答
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);
}

这个包装器上会有未来的元数据属性,例如响应时间戳,所以使用它不是一个坏主意!

于 2010-03-31T19:28:16.230 回答
5

与@Alexandre Jasmin 的答案类似,您可以使用中间 JsonSerializer 进行转换,而不是使用高级JsonConverton .ToString()。不知道是不是更有效率...

参考:

例子:

var root = JObject.Parse(jsonString);
var serializer = new JsonSerializer();
var expectedUserObject = serializer.Deserialize<User>(root["user"].CreateReader());
于 2013-01-25T17:47:45.637 回答