c# - Why doesn't Json.net properly serialize a class derived from TreeNode? -
i have class inherited treenode
when try serialize returns string that's not json string (as expected).
for example:
string json = jsonconvert.serializeobject(new a());
output:
"treenode: "
where a
defined as:
public class : treenode { public int x { get; set; } }
if remove treenode
inheritance, output is:
{"x":0}
why doesn't serialize property if it's inherited treenode
? note: filter class serialize public properties of a
class, using contract:
public class shouldserializecontractresolver : defaultcontractresolver { private list<string> propertiesnames; public shouldserializecontractresolver(type type) { this.propertiesnames = type.getproperties(bindingflags.public | bindingflags.instance | bindingflags.declaredonly) .select(p => p.name) .tolist(); } protected override jsonproperty createproperty(memberinfo member, memberserialization memberserialization) { jsonproperty property = base.createproperty(member, memberserialization); property.shouldserialize = instance => { return propertiesnames.contains(property.propertyname); }; return property; } }
and serialize object using:
shouldserializecontractresolver contract = new shouldserializecontractresolver(typeof(customtreenode)); jsonserializersettings jsonserializersettings = new jsonserializersettings() { contractresolver = contract }; string json = jsonconvert.serializeobject(groups, formatting.indented, jsonserializersettings);
but returns same invalid output mentioned in start of topic.
if you're talking system.windows.forms.treenode
reason seeing behavior because treenode
has [typeconverter]
attribute applied it, causes json.net serialize simple string value instead of object.
you can work way want in couple of different ways.
apply
[jsonobject]
attribute custom treenode class[jsonobject] public class : treenode { ... }
or, override
createcontract()
method in customcontractresolver
such explicitly creates object contract custom type:public class shouldserializecontractresolver : defaultcontractresolver { private type mytype; private list<string> propertiesnames; public shouldserializecontractresolver(type type) { mytype = type; this.propertiesnames = type.getproperties(bindingflags.public | bindingflags.instance | bindingflags.declaredonly) .select(p => p.name) .tolist(); } protected override jsoncontract createcontract(type objecttype) { if (objecttype == mytype) { return createobjectcontract(objecttype); } return base.createcontract(objecttype); } protected override jsonproperty createproperty(memberinfo member, memberserialization memberserialization) { jsonproperty property = base.createproperty(member, memberserialization); property.shouldserialize = instance => { return propertiesnames.contains(property.propertyname); }; return property; } }
Comments
Post a Comment