Cara deserialize objek JObject ke .NET

241

Saya senang menggunakan perpustakaan Newtonsoft JSON . Sebagai contoh, saya akan membuat JObjectdari objek .NET, dalam hal ini contoh Pengecualian (mungkin atau mungkin bukan subkelas)

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

sekarang saya tahu perpustakaan dapat deserialize teks JSON (yaitu string) ke suatu objek

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

tapi yang saya cari adalah:

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

Ya sudah jelas bahwa saya bisa beralih dari JObjectkembali ke teks JSON dan kemudian menggunakan fungsi deserialize, tapi itu tampaknya mundur bagi saya.

Sebastian
sumber

Jawaban:

489

Menurut posting ini , jauh lebih baik sekarang:

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

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

Dokumentasi: Konversi JSON ke Jenis

Tien Do
sumber
10
Adakah gagasan tentang implikasi kinerja di sini? Apakah refleksi akan digunakan setiap saat?
Shaun Rowan
1
Apakah mungkin untuk melakukan ini dengan JsonConverter khusus?
Justin Skiles
3
Terima kasih atas petunjuknya. Itu banyak membantu saya. Biarkan saya menambahkan sesuatu: Dalam metode generik di mana saya menggunakan tipe T, saya memerlukan sesuatu seperti result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);untuk berhasil mengonversinya (note - valueadalah objek yang berasal dari database yang mungkin merupakan JObject atau sesuatu yang lain di mana hasil kasus harus nol).
Matt
@ShaunRowan Bermain-main dengan kode di Linqpad, itu memang terlihat seperti refleksi yang digunakan untuk mencocokkan properti pada "level" yang sama dari objek target seperti bidang yang sesuai dalam objek JSON. Nama properti Anda harus cocok dengan nama bidang JSON, dan jenis properti Anda harus tipe yang kompatibel.
BobbyA
dan gunakan jobject.ToObject(myObject.GetType())jika Anda tidak tahu jenis objek.
Tohid
45

Dari dokumentasi saya menemukan ini

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

Definisi kelas untuk Personharus kompatibel dengan yang berikut:

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

Edit

Jika Anda menggunakan versi terbaru JSON.net dan tidak memerlukan serialisasi khusus, silakan lihat jawaban TienDo di atas (atau di bawah jika Anda membuat saya memilih-pilih: P), yang lebih ringkas.

Sebastian
sumber
2
Saya perlu menggunakan pendekatan ini, daripada singkatan, untuk dapat melewati pengaturan serialisasi khusus.
Justin Caldicott
Saya sedang mencari
Mark-VII
2

Terlambat, siapa tahu ada yang mencari cara lain:

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; }
}
Ivan Lopez
sumber
Ini persis seperti jawaban yang diterima .
jpaugh