2013-06-28 9 views
15

Próbuję deserializować klasę przy użyciu Json.NET i niestandardowego obiektu JsonConverter. Klasa obecnie definiuje konwerter dla domyślnej serializacji za pomocą JsonConverterAttribute. Muszę wykonać niestandardową deserializację, przekazując niestandardowy konwerter. Jednak deserializacja nadal wydaje się używać domyślnego konwertera. Jak mogę przekonać Json.NET do preferowania mojego niestandardowego konwertera?Json.NET jak zastąpić serializację dla typu, który definiuje niestandardowy JsonConverter za pomocą atrybutu?

Oto mały przykładowy kod demonstrujący problem. Używam NewtonSoft.Json 4.5.11:

void Main() 
{ 
    JsonConvert.DeserializeObject<Foo>("{}"); // throws "in the default converter" 
    var settings = new JsonSerializerSettings { Converters = new[] { new CustomConverter() } }; 
    JsonConvert.DeserializeObject<Foo>("{}", settings); // still throws "in the default converter" :-/ 
} 

[JsonConverter(typeof(DefaultConverter))] 
public class Foo { 
} 

public class DefaultConverter : JsonConverter { 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(Foo).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new Exception("in the default converter!"); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new Exception("in the default converter!"); 
    } 
} 

public class CustomConverter : JsonConverter { 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(Foo).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new Exception("in the custom converter!"); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new Exception("in the custom converter!"); 
    } 
} 

Odpowiedz

17

Musisz użyć niestandardowego przelicznika umowy. Domyślny resolwera kontraktów używa konwerterów z ustawień tylko wtedy, gdy konwerter nie jest określony dla danego typu.

class CustomContractResolver : DefaultContractResolver 
{ 
    protected override JsonConverter ResolveContractConverter (Type objectType) 
    { 
     if (typeof(Foo).IsAssignableFrom(objectType)) 
      return null; // pretend converter is not specified 
     return base.ResolveContractConverter(objectType); 
    } 
} 

Zastosowanie:

JsonConvert.DeserializeObject<Foo>("{}", new JsonSerializerSettings { 
    ContractResolver = new CustomContractResolver(), 
    Converters = new[] { new CustomConverter() }, 
});