Làm thế nào để giải tuần tự hóa một đối tượng JObject thành .NET


240

Tôi vui vẻ sử dụng thư viện Newtonsoft JSON . Ví dụ, tôi sẽ tạo một JObjecttừ một đối tượng .NET, trong trường hợp này là một trường hợp ngoại lệ (có thể hoặc không thể là một lớp con)

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

bây giờ tôi biết thư viện có thể giải tuần tự hóa văn bản JSON (tức là một chuỗi) cho một đối tượng

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

nhưng những gì tôi đang tìm kiếm là:

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

Rõ ràng là tôi có thể chuyển từ JObjecttrở lại văn bản JSON và sau đó sử dụng chức năng khử lưu huỳnh, nhưng điều đó dường như ngược với tôi.

Câu trả lời:


489

Theo bài đăng này , bây giờ tốt hơn nhiều:

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

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

Tài liệu: Chuyển đổi JSON thành một loại


10
Bất kỳ ý tưởng về ý nghĩa hiệu suất ở đây? Phản xạ sẽ được sử dụng mọi lúc?
Shaun Rowan

1
Có thể làm điều này với một JsonConverter tùy chỉnh?
Justin Skiles

3
Cảm ơn bạn đã gợi ý. Nó đã giúp tôi rất nhiều. Hãy để tôi thêm một cái gì đó: Trong một phương thức chung mà tôi đang sử dụng loại T, tôi đã yêu cầu một cái gì đó như result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);để chuyển đổi thành công nó (lưu ý - valuelà một đối tượng đến từ cơ sở dữ liệu có thể là JObject hoặc một cái gì đó khác trong trường hợp kết quả sẽ là null).
Matt

@ShaunRowan Chơi xung quanh với mã trong Linqpad, có vẻ như sự phản chiếu được sử dụng để khớp với thuộc tính ở cùng "cấp độ" của đối tượng đích như trường tương ứng trong đối tượng JSON. Tên thuộc tính của bạn phải khớp với tên của trường JSON và loại thuộc tính của bạn phải là loại tương thích.
BobbyA

và sử dụng jobject.ToObject(myObject.GetType())nếu bạn không biết loại đối tượng.
Tohid

45

Từ tài liệu tôi tìm thấy

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

Định nghĩa lớp cho Personphải tương thích với các mục sau:

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

Biên tập

Nếu bạn đang sử dụng một phiên bản JSON.net gần đây không cần tuần tự hóa tùy chỉnh, vui lòng xem câu trả lời của TienDo ở trên (hoặc bên dưới nếu bạn nâng cấp cho tôi: P), ngắn gọn hơn.


2
Tôi cần sử dụng phương pháp này, thay vì tốc ký, để có thể vượt qua các cài đặt tuần tự hóa tùy chỉnh.
Justin Caldicott

Chính xác tôi đang tìm kiếm
Mark-VII

2

Quá muộn, chỉ trong trường hợp ai đó đang tìm kiếm một cách khác:

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

Điều này trông giống hệt như câu trả lời được chấp nhận .
jpaugh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.