วิธี deserialize วัตถุ JObject to .NET


241

ฉันมีความสุขใช้ห้องสมุด Newtonsoft 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 จากนั้นใช้ฟังก์ชั่น deserialize แต่ดูเหมือนว่าจะย้อนกลับไป

คำตอบ:


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 แบบกำหนดเอง?
Justin Skiles

3
ขอบคุณสำหรับคำใบ้ มันช่วยฉันได้มาก ให้ฉันเพิ่มบางอย่าง: ในวิธีการทั่วไปที่ฉันใช้ประเภทTฉันต้องการสิ่งที่result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);จะประสบความสำเร็จในการแปลง (หมายเหตุ - valueเป็นวัตถุที่มาจากฐานข้อมูลซึ่งอาจเป็น JObject หรือสิ่งอื่นซึ่งผลลัพธ์ที่ควรจะเป็นโมฆะ)
Matt

@ShaunRowan การเล่นกับรหัสใน Linqpad ดูเหมือนว่าการสะท้อนจะใช้ในการจับคู่คุณสมบัติที่ "ระดับ" เดียวกันของวัตถุเป้าหมายเป็นเขตข้อมูลที่สอดคล้องกันในวัตถุ JSON ชื่อของคุณสมบัติของคุณจะต้องตรงกับชื่อของเขตข้อมูล JSON และประเภทของคุณสมบัติของคุณจะต้องเป็นชนิดที่เข้ากันได้
BobbyA

และใช้jobject.ToObject(myObject.GetType())ถ้าคุณไม่ทราบประเภทวัตถุ
Tohid

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 ด้านบน (หรือด้านล่างหากคุณ upvote me: P) ซึ่งสั้นกระชับกว่า


2
ฉันต้องการใช้วิธีการนี้แทนการจดชวเลข
Justin Caldicott

ตอบแน่นอนฉันกำลังค้นหา
Mark-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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.