c# - DataContractJsonSerializer serialization error: Consider using a DataContractResolver or add any types not known statically to the list -
i extending object being serialized system.runtime.serialization.json.datacontractjsonserializer
2 additional properties strings (not complex types) inheritance. .net version used .net 4.
serialization mechanism works fine base object fails object 2 additional properties seems peculiar me.
using [datacontract]
attributes on both base , inherited object , properties on both of them have [datamember]
attributes names.
both objects internal don't see how affect serialization of child object.
while debugging have observed base object step in try
block , serialized, , child blow on line serializer.writeobject(ms, sourceobject);
adding known type attribute [knowntype(typeof(onthemovebusinesscomponentjavascriptinitobject))]
on inherited object results in same error in same place.
why can't substitute base object inherited one?
childobject:
namespace onthemovelibrary.datacontrols { [datacontract] [knowntype(typeof(onthemovebusinesscomponentjavascriptinitobject))] internal class onthemovetreebusinesscomponentjavascriptinitobject : onthemovebusinesscomponentjavascriptinitobject { [datamember(name = "masterrecordid")] public string masterrecordid { get; set; } [datamember(name = "parentrecordid")] public string parentrecordid { get; set; } } }
baseobject:
namespace onthemovelibrary.datacontrols { [datacontract] internal class onthemovebusinesscomponentjavascriptinitobject : onthemovevalidatable { public onthemovebusinesscomponentjavascriptinitobject() { this.sqlstatementobject = new onthemoveselectstatement(); this.predefaults = new predefaultsobject(); this.parentassociations = new list<parentassociation>(); this.calculatedfields = new list<onthemovecalculatedfield>(); this.businesscomponentevents = new list<businesscomponentevent>(); } [datamember(name = "sqlstatementobject")] public ionthemoveselectstatement sqlstatementobject { get; set; } [datamember(name = "calculatedfields")] public list<onthemovecalculatedfield> calculatedfields { get; set; } [datamember(name = "knockoutcontextname")] public string knockoutcontextname { get; set; } [datamember(name = "observable")] public bool observable { get; set; } [datamember(name = "integrationobjectnamefornewrecords")] public string integrationobjectnamefornewrecords { get; set; } [datamember(name = "singlerecordnewflag")] public bool singlerecordnewflag { get; set; } [datamember(name = "recordindex")] public int? recordindex { get; set; } [datamember(name = "primarytablename")] public string primarytablename { get; set; } /// <summary> /// index within query string of "recordid" parameter use parent insert new records, defaulting 0 /// example, if have recordid of "a123,b123" in querystring, , set parentqsrecordidindex=1, b123 used parent object when saving /// </summary> [datamember(name = "parentrecordidquerystringindex")] public int? parentrecordidquerystringindex { get; set; } [datamember(name = "parentassociations")] public list<parentassociation> parentassociations { get; set; } [datamember(name = "applybindings")] public bool applybindings { get; set; } [datamember(name = "predefaults")] public predefaultsobject predefaults { get; set; } /// <summary> /// gets or sets list of <see cref="businesscomponentevent">businesscomponentevents</see>. /// </summary> [datamember(name = "businesscomponentevents")] public list<businesscomponentevent> businesscomponentevents { get; set; } [datamember(name = "automaticleadingwildcards")] public bool? automaticleadingwildcards { get; set; } [datamember(name = "automatictrailingwildcards")] public bool? automatictrailingwildcards { get; set; } [datamember(name = "enableaggregatefields")] public bool? enableaggregatefields { get; set; } public override void validateproperties() { this.validateproperty("sqlstatementobject", this.sqlstatementobject != null ? this.sqlstatementobject.tostring() : null); this.sqlstatementobject.validateproperties(); } } }
serialization mechanism:
public static string objecttojson<tvalue>(tvalue sourceobject) { string result = null; type type = typeof(tvalue); if (type == typeof(object)) { return callobjecttojsonwithspecifictype(sourceobject); } type[] knowntypes = new[] { typeof(onthemoveselectstatement), typeof(onthemovecustomselectstatement) }; var serializer = new datacontractjsonserializer(type, knowntypes); var ms = new memorystream(); try { serializer.writeobject(ms, sourceobject); result = encoding.utf8.getstring(ms.toarray()); } { ms.close(); } return result; }
figured out myself.
instead of adding base class type in attribute class inherits
[datacontract] [knowntype(typeof(onthemovebusinesscomponentjavascriptinitobject))] internal class onthemovetreebusinesscomponentjavascriptinitobject : onthemovebusinesscomponentjavascriptinitobject
one has opposite - add base class attribute child class type (which breaks object oriented design since base class should never know inherits it).
[datacontract] [knowntype(typeof(onthemovetreebusinesscomponentjavascriptinitobject))] internal class onthemovebusinesscomponentjavascriptinitobject : onthemovevalidatable
Comments
Post a Comment