Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET how to override serialization for a type that defines a custom JsonConverter via an attribute?

Tags:

c#

json.net

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!");
    }
}
like image 452
ChaseMedallion Avatar asked Jun 28 '13 15:06

ChaseMedallion


People also ask

How does the Jsonproperty attribute affect JSON serialization?

JsonPropertyAttribute indicates that a property should be serialized when member serialization is set to opt-in. It includes non-public properties in serialization and deserialization. It can be used to customize type name, reference, null, and default value handling for the property value.

Which of the following attributes are required to ignore properties for JSON serializer?

To ignore individual properties, use the [JsonIgnore] attribute.

What is JSON serialization exception?

JsonSerializationException(String, String, Int32, Int32, Exception) Initializes a new instance of the JsonSerializationException class with a specified error message, JSON path, line number, line position, and a reference to the inner exception that is the cause of this exception.


1 Answers

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() },
});
like image 198
Athari Avatar answered Oct 12 '22 20:10

Athari