Click or drag to resize
Json.NET

Serialization using ContractResolver

 

The IContractResolver interface provides a way to customize how the JsonSerializer serializes and deserializes .NET objects to JSON without placing attributes on your classes.

Anything that can be set on an object, collection, property, etc, using attributes or methods to control serialization can also be set using an IContractResolver.

Note Note

For performance you should create a contract resolver once and reuse instances when possible. Resolving contracts is slow and implementations of IContractResolver typically cache contracts.

DefaultContractResolver

The DefaultContractResolver is the default resolver used by the serializer. It provides many avenues of extensibility in the form of virtual methods that can be overridden.

CamelCasePropertyNamesContractResolver

CamelCasePropertyNamesContractResolver inherits from DefaultContractResolver and simply overrides the JSON property name to be written in camelcase.

ContractResolver
Product product = new Product
{
    ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc),
    Name = "Widget",
    Price = 9.99m,
    Sizes = new[] { "Small", "Medium", "Large" }
};

string json =
    JsonConvert.SerializeObject(
        product,
        Formatting.Indented,
        new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
        );

//{
//  "name": "Widget",
//  "expiryDate": "2010-12-20T18:01:00Z",
//  "price": 9.99,
//  "sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}
Custom IContractResolver Examples
Use JsonConverter with IContractResolver
public class ConverterContractResolver : DefaultContractResolver
{
    public new static readonly ConverterContractResolver Instance = new ConverterContractResolver();

    protected override JsonContract CreateContract(Type objectType)
    {
        JsonContract contract = base.CreateContract(objectType);

        // this will only be called once and then cached
        if (objectType == typeof(DateTime) || objectType == typeof(DateTimeOffset))
        {
            contract.Converter = new JavaScriptDateTimeConverter();
        }

        return contract;
    }
}

This example sets a JsonConverter for a type using an IContractResolver. Using a contract resolver here is useful because DateTime is not your own type and it is not possible to place a JsonConverterAttribute on it.

Conditional properties with IContractResolver
public class ShouldSerializeContractResolver : DefaultContractResolver
{
    public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();

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

        if (property.DeclaringType == typeof(Employee) && property.PropertyName == "Manager")
        {
            property.ShouldSerialize =
                instance =>
                {
                    Employee e = (Employee)instance;
                    return e.Manager != e;
                };
        }

        return property;
    }
}

This example sets up conditional serialization for a property using an IContractResolver. This is useful if you want to conditionally serialize a property but don't want to add additional methods to your type.

See Also