Как десериализовать объект JObject в .NET


241

Я с радостью использую библиотеку Newtonsoft JSON . Например, я бы создал объект JObjectиз .NET, в данном случае экземпляр Exception (может быть или не быть подклассом)

if (result is Exception)
    var jobjectInstance = JObject.FromObject(result);

теперь я знаю, что библиотека может десериализовать текст JSON (т.е. строку) в объект

// only works for text (string)
Exception exception = JsonConvert.DeserializeObject<Exception>(jsontext); 

но то, что я ищу, это:

// now i do already have an JObject instance
Exception exception = jobjectInstance.????

Ясно, что я могу JObjectвернуться к тексту JSON и затем использовать функцию десериализации, но это кажется мне обратным.

Ответы:


489

Согласно этому посту , теперь намного лучше:

// pick out one album
JObject jalbum = albums[0] as JObject;

// Copy to a static Album instance
Album album = jalbum.ToObject<Album>();

Документация: конвертировать JSON в тип


10
Любые идеи о последствиях производительности здесь? Будет ли отражение использоваться каждый раз?
Шон Роуэн

1
Возможно ли это сделать с помощью специального JsonConverter?
Джастин Скилз

3
Спасибо за подсказку. Это мне очень помогло. Позвольте мне добавить кое-что: в универсальном методе, где я использую тип T, мне требовалось что-то вроде result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);успешного преобразования (примечание - valueэто объект, поступающий из базы данных, который может быть JObject или что-то еще, в этом случае результат должен быть нулевым).
Мэтт

@ShaunRowan Играя с кодом в Linqpad, похоже, что отражение используется для сопоставления свойства на том же «уровне» целевого объекта, что и соответствующее поле в объекте JSON. Имя вашего свойства должно совпадать с именем поля JSON, а тип вашего свойства должен быть совместимым типом.
Бобби

и используйте, jobject.ToObject(myObject.GetType())если вы не знаете тип объекта.
Тохид

45

Из документации я нашел это

JObject o = new JObject(
   new JProperty("Name", "John Smith"),
   new JProperty("BirthDate", new DateTime(1983, 3, 20))
);

JsonSerializer serializer = new JsonSerializer();
Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person));

Console.WriteLine(p.Name);

Определение класса для Personдолжно быть совместимо со следующим:

class Person {
    public string Name { get; internal set; }
    public DateTime BirthDate { get; internal set; }
}

редактировать

Если вы используете последнюю версию JSON.net и не нуждаетесь в настраиваемой сериализации, см. Ответ TienDo выше (или ниже, если вы проголосуете за меня: P), что более кратко.


2
Мне нужно было использовать этот подход, а не стенографию, чтобы передать пользовательские настройки сериализации.
Джастин Колдикотт

Точный и я ищу
Марк-VII

2

Слишком поздно, на тот случай, если кто-то ищет другой путь:

void Main()
{
    string jsonString = @"{
  'Stores': [
    'Lambton Quay',
    'Willis Street'
  ],
  'Manufacturers': [
    {
      'Name': 'Acme Co',
      'Products': [
        {
          'Name': 'Anvil',
          'Price': 50
        }
      ]
    },
    {
      'Name': 'Contoso',
      'Products': [
        {
          'Name': 'Elbow Grease',
          'Price': 99.95
        },
        {
          'Name': 'Headlight Fluid',
          'Price': 4
        }
      ]
    }
  ]
}";

    Product product = new Product();
    //Serializing to Object
    Product obj = JObject.Parse(jsonString).SelectToken("$.Manufacturers[?(@.Name == 'Acme Co' && @.Name != 'Contoso')]").ToObject<Product>();

    Console.WriteLine(obj);
}


public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Это выглядит в точности как принятый ответ .
jpaugh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.