Десериализация JSON в объект с помощью Json.NET - PullRequest
25 голосов
/ 31 марта 2010

Я немного играю с новым 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: Обязательное свойство 'user_id' не найдено в формате JSON.

Это потому, что объект JSON является массивом? Если да, то как я могу десериализовать его для одного объекта User?

Заранее спасибо!

Ответы [ 3 ]

36 голосов
/ 31 марта 2010

Если вы не хотите создавать класс-оболочку, вы также можете получить доступ к пользователю следующим образом:

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 .

27 голосов
/ 31 марта 2010

Как сказал Александр Жасмин в комментариях к вашему вопросу, полученный 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);
}

В этой оболочке будут свойства будущих метаданных, например, отметка времени ответа, так что неплохо было бы ее использовать!

5 голосов
/ 25 января 2013

Подобно ответу @Alexandre Jasmin , вы можете использовать промежуточный JsonSerializer для преобразования вместо использования высокоуровневого JsonConvert в .ToString().Не знаю, будет ли это более эффективным ...

Рекомендации:

Пример:

var root = JObject.Parse(jsonString);
var serializer = new JsonSerializer();
var expectedUserObject = serializer.Deserialize<User>(root["user"].CreateReader());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...