2013-04-10 20 views
9

Tôi không chắc chắn tại sao mọi người chưa hỏi về câu hỏi này nhưng tôi đang cố gắng tuần tự hóa các kiểu đơn giản của một đối tượng đã cho sử dụng giao diện IContractResolver. Tôi không thực sự muốn đánh dấu từng thuộc tính bằng cách sử dụng phương thức ShouldSerialize hoặc JsonDataAttribute hoặc bất kỳ thứ gì như thế này.Sắp xếp theo kiểu đơn giản chỉ bằng cách sử dụng Json.Net

Những gì tôi đã làm cho đến nay thể hiện như sau trên LinqPad

Một số lớp mẫu để serialize

class Customer 
{ 
    public List<Order> Orders {get;set;} 
    public int CustomerId {get;set;} 
    public string[] Addresses {get;set;} 
} 

class Order 
{ 
    public int OrderId{get;set;} 
    public string Name {get;set;} 
    public int Amount {get;set;} 
    public Order PreviousOrder {get;set;} 
} 

Một phương pháp mở rộng để serialize tất cả các đối tượng

static class ExtensionMethods 
{ 
    public static string JsonSerialize (this object obj) 
    { 
     var settings = new JsonSerializerSettings(); 
     settings.ContractResolver = new MyContractResolver(); 
     settings.DefaultValueHandling = DefaultValueHandling.Ignore; 
     settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
     return JsonConvert.SerializeObject(obj,settings); 
    } 
} 

Lớp giải quyết hợp đồng tùy chỉnh của tôi

public class MyContractResolver: DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member,memberSerialization); 
     property.ShouldSerialize = instance => instance.GetType().IsPrimitive || instance.GetType() == typeof(string) || instance.GetType() == typeof(decimal); 
     return property; 
    } 
} 

và phương pháp chính:

void Main() 
{ 
    var customer = new Customer 
       { 
        Orders = ProduceSomeOrders(), 
        Addresses = new string[] {"9450 S. Small Street Dr.","9521 Flintstone Dr. S"}, 
        CustomerId = 1 
       }; 

    var jsonOrder = customer.JsonSerialize(); 
    jsonOrder.Dump(); 
} 

Tôi chỉ muốn serialize loại mẫu như int, double, string, decimal, bool vv nhưng không mảng, bộ sưu tập, các đối tượng tùy chỉnh vv và nó sẽ chỉ điều hướng ở cấp độ đầu tiên, không phải cấp 2 trở lên. Tôi thực sự tự hỏi tại sao không có bất kỳ phương pháp đơn giản nào thực hiện điều này trong Json.Net.

Đây là đầu ra khi tôi chạy mã này: (một json trống)

{}

tôi đã nhận ra một điều khi tôi chạy mã này, các tham số đầu tiên member qua vào phương thức CreateProperty là chính đối tượng chính trong trường hợp này là phiên bản Customer. Nhưng kể từ khi điều này sẽ làm việc cho tất cả các loại tôi chỉ không muốn nói instance.GetType() == typeof(Customer) hoặc một cái gì đó như thế này trong phương pháp. Sản lượng dự kiến ​​trong trường hợp này chỉ là CustomerId trong trường hợp này.

Bạn có biết cách nào để xử lý sự cố của mình không?

+0

kết quả dự kiến ​​của serialization là gì? Dựa trên những gì tôi đọc nó nên chứa chỉ CustomerID, đó là chính xác? – Patrick

+0

@Patrick: Bạn nói đúng! – Tarik

+0

Trong phương thức JsonSerialize, có thể lặp lại các thuộc tính của "cá thể trên cùng", để tuần tự hóa các thuộc tính con của nó, và sau đó bằng cách nào đó trộn chúng lại với nhau thành một chuỗi json hợp lệ không? – Patrick

Trả lời

5

Bằng cách thay đổi phương thức bên dưới, tôi nhận được kết quả: {"CustomerId": 1}. Đây có phải là những gì bạn đang tìm kiếm?

public class MyContractResolver:DefaultContractResolver 
{ 
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
{ 
    var property = base.CreateProperty(member,memberSerialization); 

    var propertyType = property.PropertyType; 
    if(propertyType == typeof(int) 
     || propertyType == typeof(string)){ 
     property.ShouldSerialize = instance => true; 
    } 
    else 
    { 
     property.ShouldSerialize = instance => false; 
    } 
    return property; 
} 
} 
2

Thay vì phương pháp trọng CreateProperty, tôi trọng GetSerializableObjects phương pháp như nó mang lại cho tất cả các thành viên có thể, tôi sẽ nhận được:

public class MyContractResolver: DefaultContractResolver 
{ 
    protected override List<MemberInfo> GetSerializableMembers(Type objectType) 
    { 
     var members = base.GetSerializableMembers(objectType); 
     var filteredMembers = new List<MemberInfo>(); 
     members.ForEach(m=>{ 
      if(m.MemberType == MemberTypes.Property) 
      { 
       PropertyInfo info = (PropertyInfo) m; 
       var type = info.PropertyType; 
       if(type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) 
       { 
        filteredMembers.Add(m); 
       } 
      } 
     }); 
     return filteredMembers; 
    } 
} 
Các vấn đề liên quan