2016-02-19 19 views
5

Tôi có một kịch bản với một lớp được định nghĩa như sau:Conditional serialization/deserialization tài sản đối tượng với json.net

class MyObject 
{ 
    public DataDictionary MyObjectData { get; set; } 

    public bool ShouldSerializeMyObjectData() { return true; } 
    public bool ShouldDeserializeMyObjectData() { return false; } 
} 

Khi tôi cố gắng để serialize/deserialize rằng lớp với JSON.net, phải mất các ShouldSerialize vào tài khoản, nhưng không phải là ShouldDeserialize.

Theo tài liệu, cả hai đều hoạt động giống như cách tôi đoán. Có điều gì đặc biệt tôi nên biết không? Nói chung, tôi nên xử lý các kịch bản như thế nào ở nơi tôi muốn tuần tự hóa một thuộc tính chứ không phải deserialize nó?

Tôi đang sử dụng Json.NET 8.0 nếu điều đó quan trọng.

Cảm ơn sự giúp đỡ của bạn.

+0

Nó không nói bất cứ điều gì về 'ShouldDeserialize' trong [tài liệu] (http://www.newtonsoft.com/json/help/html/ConditionalProperties.htm). Tại sao bạn muốn serialize một cái gì đó nhưng không deserialize nó? – kjbartel

+0

@kjbartel Cùng một mô hình cho tuần tự hóa/deserialization nhưng khi deserializing có một liên kết trung gian (ghét) để truy cập tài sản cụ thể đó. –

+2

Xem thêm [Thuộc tính tuần tự hóa, nhưng không thuộc tính Deserialize trong Json.Net] (http: // stackoverflow.com/q/31731320/10263) –

Trả lời

6

Câu trả lời ngắn cho câu hỏi của bạn là, tự động kiểm tra ShouldDeserialize{PropertyName}() hiện không được triển khai mặc dù ShouldSerialize{PropertyName}() là. Câu trả lời và cách giải quyết lâu hơn theo sau.

Lớp JsonProperty được Json.NET sử dụng trong nội bộ để xác định hợp đồng về cách ánh xạ một thuộc tính JSON tới thành phần .NET hoặc tham số hàm tạo. Nó có hai thuộc tính vị ngữ, ShouldSerializeShouldDeserialize rằng, khi không rỗng, ngăn chặn một thuộc tính không bị tuần tự hóa và được loại bỏ theo thứ tự. Khởi tạo mỗi JsonProperty là công việc của ContractResolver. Đối với mỗi thuộc tính {PropertyName}, số default contract resolver của Json.NET tự động kiểm tra sự hiện diện của phương thức public bool ShouldSerialize{PropertyName}(). Nếu một phương thức như vậy tồn tại, nó sẽ thêm một lời gọi vào nó trong thuộc tính ShouldSerialize, do đó triệt tiêu chuỗi tuần tự khi phương thức trả về false. Điều này đã được triển khai vì kiểm soát việc tuần tự hóa thuộc tính thông qua phương thức ShouldSerialize{PropertyName}() là mẫu chuẩn được hỗ trợ bởi, ví dụ: XmlSerializer. Để biết thêm thông tin, hãy xem Json.NET release notes có liên quan.

Ví dụ, trong lớp sau, tuần tự của MyObjectData sẽ bị đè nén trừ MyObjectData.Count > 0:

class MyObject 
{ 
    public DataDictionary MyObjectData { get; set; } 

    public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; } 
} 

JsonProperty.ShouldDeserialize, tuy nhiên, nó không bao giờ theo quy định của hợp đồng phân giải mặc định. Điều này có thể là do thực tế là không có mẫu chuẩn cho việc deserialization tương đương với ShouldSerialize{PropertyName}() và do đó Newtonsoft không bao giờ có bất kỳ yêu cầu nào để thực hiện mẫu đó. Tuy nhiên, như bạn đã nhận thấy, cơ sở hạ tầng để hỗ trợ mô hình như vậy tồn tại, và vì vậy các ứng dụng có thể tạo ra custom contract resolvers làm điều đó. Trong thực tế, Json.NET có một ví dụ về giải quyết hợp đồng như vậy trong riêng test suite của nó:

public class ShouldDeserializeContractResolver : DefaultContractResolver 
{ 
    public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver(); 

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 

     MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name); 

     if (shouldDeserializeMethodInfo != null) 
     { 
      property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); }; 
     } 

     return property; 
    } 
} 

public class ShouldDeserializeTestClass 
{ 
    [JsonExtensionData] 
    public IDictionary<string, JToken> ExtensionData { get; set; } 

    public bool HasName { get; set; } 
    public string Name { get; set; } 

    public bool ShouldDeserializeName() 
    { 
     return HasName; 
    } 
} 

Nếu bạn muốn có điều kiện ngăn chặn deserialization tài sản ngay cả khi hiện diện trong JSON, bạn có thể xem xét sử dụng (và caching) người giải quyết hợp đồng này.

+0

Điều này gần giống với [câu trả lời khác] của bạn (http://stackoverflow.com/a/31732029/1730559) về câu hỏi trùng lặp. Tại sao bạn không chỉ gắn cờ câu hỏi này là trùng lặp? – kjbartel

Các vấn đề liên quan