2011-08-09 41 views
15

Có thể ghi đè độ phân giải loại bằng JSON.NET dựa trên thuộc tính của đối tượng JSON không? Dựa trên các API hiện có, có vẻ như tôi cần một cách để chấp nhận một JsonPropertyCollection và trả về Type để được tạo.Độ phân giải loại dựa trên thuộc tính trong JSON.NET

LƯU Ý: Tôi biết về số TypeNameHandling attribute, nhưng điều đó sẽ thêm một thuộc tính $type. Tôi không có quyền kiểm soát JSON nguồn.

Trả lời

14

Có vẻ như điều này được xử lý bằng cách tạo một tùy chỉnh JsonConverter và thêm nó vào JsonSerializerSettings.Converters trước khi deserialisation.

nonplus đã để lại mẫu tiện dụng trên JSON.NET discussions board trên Codeplex. Tôi đã sửa đổi mẫu để trả về tùy chỉnh Type và trì hoãn cơ chế tạo mặc định, thay vì tạo đối tượng đối tượng tại chỗ.

abstract class JsonCreationConverter<T> : JsonConverter 
{ 
    /// <summary> 
    /// Create an instance of objectType, based properties in the JSON object 
    /// </summary> 
    protected abstract Type GetType(Type objectType, JObject jObject); 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(T).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, 
     object existingValue, JsonSerializer serializer) 
    { 
     JObject jObject = JObject.Load(reader); 

     Type targetType = GetType(objectType, jObject); 

     // TODO: Change this to the Json.Net-built-in way of creating instances 
     object target = Activator.CreateInstance(targetType); 

     serializer.Populate(jObject.CreateReader(), target); 

     return target; 
    } 
} 

Và đây là cách sử dụng ví dụ (cũng được cập nhật như đã đề cập ở trên):

class VehicleConverter : JsonCreationConverter<Vehicle> 
{ 
    protected override Type GetType(Type objectType, JObject jObject) 
    { 
     var type = (string)jObject.Property("Type"); 
     switch (type) 
     { 
      case "Car": 
       return typeof(Car); 
      case "Bike": 
       return typeof(Bike); 
     } 

     throw new ApplicationException(String.Format(
      "The given vehicle type {0} is not supported!", type)); 
    } 
} 
+0

gì về trừu tượng 'phương pháp WriteJson' chưa thực hiện? –

+1

@ CanPoyrazoğlu Bạn sẽ muốn ghi đè lên thuộc tính CanWrite và đặt nó thành false. Điều này sẽ có bộ chuyển đổi rơi trở lại hành vi mặc định của nó. – bmeredith

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