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 customcontractresolversuch 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