17

I am trying to deserialize a class using Json.NET and a custom JsonConverter object. The class currently defines a converter for default serialization using the JsonConverterAttribute. I need to do a custom deserialization by passing in a custom converter. However, the deserialization still seems to be using the default converter. How can I get Json.NET to prefer my custom converter?

Here's a bit of sample code that demonstrates the issue. I'm using 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!"); } } 

1 Answer 1

22

You need to use custom contract resolver. Default contract resolver uses converters from settings only if converter is not specified for the type.

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

Usage:

JsonConvert.DeserializeObject<Foo>("{}", new JsonSerializerSettings { ContractResolver = new CustomContractResolver(), Converters = new[] { new CustomConverter() }, }); 
Sign up to request clarification or add additional context in comments.

1 Comment

DefaultContractResolver has changed significantly since this post so this solution no longer works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.