We use Newtonsoft Json.NET heavily in our project to control our JSON serialization. For the most part, it works absolutely perfectly out-of-the-box, but every now and then, we need to customize the way that serialization works for a particular object.
Such an occasion occurred today. Basically, I have a list of EmployeeActivity objects – where each instance is a subclass of EmployeeActivity. So, for example:
public abstract class EmployeeActivity
{
public TimeSpan Start { get; set; }
public TimeSpan Stop { get; set; }
public virtual bool IsAvailable
{
get { return false; }
}
}
public class AbsenceActivity : EmployeeActivity
{
public string Reason { get; set; }
}
public class BreakActivity : EmployeeActivity
{
public string BreakName { get; set; }
}
json.NET does a perfect job of serializing my objects, and they rebuild perfectly when I’m back in javascript land – however, I have no way of knowing the actual type of each activity in my array! To alleviate this, I wanted to create my own serializer which also injected the type name into each of the serialized objects – or at least, that’s what I thought I wanted to do!
As it turns out, there’s a bit of an easier option. JsonConvert uses a ContractResolver in order to work out how to Serialize/Deserialize each class, and you can override the default contract resolver when running serialization:
// This class contains the activity list
ActivityViewModel = new ActivityViewModel(DateTime.Today);
// Serialize using a custom contract resolver
string jsonViewModel = JsonConvert.SerializeObject(viewModel,
Formatting.None, new JsonSerializerSettings
{
ContractResolver = new ActivityJsonContractResolver()
});
The contract resolver’s job is to return a JsonContract which describes the object to be returned. For a POCO, this would typically be an instance of JsonObjectContract, which (amongst other things) describes the properties of the class which should be serialized.
So, all I needed to do was to extend the contract for subclasses of EmployeeActivity, such that it inherited a new Property to be serialized:
public class DiaryActivityJsonContractResolver : DefaultContractResolver
{
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
JsonObjectContract contract = base.CreateObjectContract(objectType);
if (typeof(EmployeeActivity).IsAssignableFrom(objectType))
{
contract.Properties.Add(new JsonProperty
{
Readable = true,
ShouldSerialize = value => true,
PropertyName = "Type",
PropertyType = typeof(string),
Converter = ResolveContractConverter(typeof(string)),
ValueProvider = new StaticValueProvider(objectType.Name)
});
}
return contract;
}
}
Truth be told, I’m not 100% sure if I need to implement as many of the properties on the JsonProperty that I’m creating. But you can see what’s going on here – I’m effectively telling the object contract that there’s an additional property called Type which needs to be serialized, that it’s a string, and that it should return whatever value is resolved by the StaticValueProvider. Speaking of which, here’s the last piece of the puzzle – a simple value resolver that always returns the same value:
/// <summary>
/// JSON value provider that always returns a static value
/// </summary>
public class StaticValueProvider : IValueProvider
{
private readonly object _staticValue;
public StaticValueProvider(object staticValue)
{
_staticValue = staticValue;
}
public void SetValue(object target, object value)
{
throw new NotSupportedException();
}
public object GetValue(object target)
{
return _staticValue;
}
}
json.NET is fantastic, and it’s very extensible, but finding out where to start and what to do can be a little bit tricky. I managed to figure this out only by downloading the source files and poking through the code myself; hopefully this will be helpful to someone else in the same situation!




