Re-serializing gives different valued object

Feb 23, 2009 at 10:05 PM
I'am using JSON.NET as a lib for interacting with CouchDB, which stores database documents as JSON documents.
For this, I am using the following pattern:

class SuperKlass {
public string SuperProp { get; set; }
public SuperKlass() { SuperProp = "default superprop"; }
}
class SubKlass : SuperKlass {
public string SubProp { get; set; }
public SubKlass(string subprop) { SubProp = subprop; }
}
Now serializing works correctly, but deserializing of the following object 'i' does not:
  SubKlass i = new SubKlass("my subprop");
  i.SuperProp = "overrided superprop";
gives as serialization
  {"SubProp":"my subprop","SuperProp":"overrided superprop"}
(which is good), but re-serializes as:
  {"SubProp":"my subprop","SuperProp":"default superprop"}
...which is bad.

After debugging it occurs me why: because the subclass has no parameterless constructor, the deserializer will call the only constructor available, which is good. However, it forgets to fill in the properties which are not used by the constructor. So in this case property subprop is correctly filled in, but superprop does not have a parameter in the constructor. However, superprop can and should be filled in by using the property itself!

Since I do not want to enforce all subclasses to have meaningless parameterless constructors because of this bug / missing feature, what could I do?

Thanks,
Rutger.
Coordinator
Mar 3, 2009 at 4:12 AM
Hi

I have changed the serializer so that it will attempt to assign any values that weren't used in the constructor to the object's properties. This fixes the scenario in your sample code.

It was pretty tricky :)

I don't know when I'll check it in but I'll post here when I do.

~ James
Coordinator
Mar 14, 2009 at 1:42 AM
Source code is in CodePlex if you want to grab it and build a copy.

http://json.codeplex.com/SourceControl/ListDownloadableCommits.aspx
Apr 30, 2009 at 11:02 PM
Thanks a lot, just what I needed! (...next to the IMappingResolver).