Як дезаріалізувати об’єкт JObject to .NET


241

Я із задоволенням користуюся бібліотекою Ньютонсофт JSON . Наприклад, я створив би JObjectз .NET-об'єкта, в цьому випадку екземпляр винятку (може бути, а може і не підкласом)

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
Будь-які ідеї щодо продуктивних наслідків тут? Чи використовуватиметься рефлексія щоразу?
Shaun Rowan

1
Чи можливо це зробити за допомогою спеціального JsonConverter?
Джастін Скілз

3
Дякую за підказку Це мені дуже допомогло. Дозвольте додати щось: у загальному методі, де я використовую тип T, мені потрібно було щось на зразок result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);успішного перетворення його (зауважте - valueце об'єкт, що надходить із бази даних, який може бути JObject або щось інше, і в цьому випадку результат повинен бути нульовим).
Метт

@ShaunRowan Граючи з кодом у Linqpad, це виглядає так, що відображення використовується для відповідності властивості на тому ж "рівні" цільового об'єкта, що і відповідне поле в об'єкті JSON. Назва вашої власності повинна відповідати імені поля JSON, а тип вашої власності повинен бути сумісним типом.
BobbyA

і використовувати, 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; }
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.