Changing a serialized member with contract resolver

Mar 25, 2010 at 6:18 PM
Edited Mar 25, 2010 at 6:21 PM


I was wondering if it was possible to handle this situation. Say you have this class:


public interface IMarker {
   string Id {get;set;}



public class Person : IMarker {

      string Id {get;set;}

     string Name {get;set;}

     Person Mother {get;set;}

     Person Father {get;set;}



Now, if you created an instance of person as:


var child = new Person { 
Id = "123",
Name = "Child",
Mother = new Person { Id = "333", Name = "ZeeMum" },
Father = new Person { id = "999", Name = "ZeeDad" } };

( The mother and father properties are unimportant in this case if they are assigned directly like this as the only thing that matters is the Id )

How would you go about serializing the child instance as:




  Id: "123",
  Name: "Child",
  Mother: {
    table: "Person",
    id: "333"
  Father: {
    table: "Person",
    id: "999"


The specific part I need to change is the serialization of only properties on a type which are convertible to IMarker, in this case Mother/Father, but not Child directly, I don't need to change the way the whole class is serialized if it is the root in the relation.

The idea is to then, on deserializing the child, create a proxy for the Mother/Fater properties, with a reference to the table/id, and from the perform lazy initialization of either on use.


Mar 25, 2010 at 8:20 PM

Got it working :D


Just inherit from the DefaultContractResolver and override the CreateProperty method with what ever you are looking for, in my case IMarker:


if (prop == null || !typeof(IMarker).IsAssignableFrom(prop.PropertyType))
                return base.CreateProperty(contract, member);

            var converter = new TempRefConverter(member);


Create a JSonProperty from there on with the specifi converter.

So in the converter you could do something like:

public override void WriteJson(...) {
                if (value == null)

                var v = (IMarker)value;

                var dic = new EntityReference {
                    C = _memberInfo.Name,
                    I = v._id

                serializer.Serialize(writer, dic);

public override object ReadJson(...) {
                var er = new EntityReference();
                serializer.Populate(reader, er);

                var inst = Activator.CreateInstance(_prop.PropertyType);
                ((IMarker)inst)._id = Guid.Parse(er.I.ToString());

                return inst;


Err, IMarker is now a Guid in case you where wondering.

Hope this helps.


And thanks to the Json.Net team for a beautiful library.