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 |
---|
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. |
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 inherits from DefaultContractResolver and simply overrides the JSON property name to be written in camelcase.
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" // ] //}
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.
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.