The serialization and deserialization of Newtonsoft.json is very mature and useful, and recently encountered a problem in the deserialization of a polymorphic type, which can only be converted to a base class after deserialization, but not to a subclass. After a query from the Internet, you need to write a type of converter, below we step by step:
1. First describe the definition of the type, in order to do this experiment, I define a base class and two subclasses, and then I want to serialize the object containing the collection of this base class.
namespacelexsry{usingNewtonsoft.json; usingSystem.Collections.Generic; classDemodata {[Jsonproperty ("demoid")] Public intdemoid {Get;Set; } [Jsonproperty ("Demos")] PublicList<demobase> Demos {Get;Set; } } Public classdemobase {[Jsonproperty ("ID")] Public intId {Get;Set; } [Jsonproperty ("name")] Public stringName {Get;Set; } [Jsonproperty ("type")] Public stringType {Get;Set; } } Public classdemoa:demobase {[Jsonproperty ("Color")] Public stringColor {Get;Set; } } Public classdemob:demobase {[Jsonproperty ("size")] Public Double[] Size {Get;Set; } }}
2. Serialization, deserialization method. Use JsonConvert when deserializing. deserializeobject<T> (string value, param jsonconverter[] converter). Create the appropriate subclass by defining jsonconverter yourself.
in this demo, I first created an abstract classJsoncreationconverter<T:Jsonconverter,
second, for the Demobase, I created aJsondemoconverter:Jsoncreationconverter<Demobase>
classJsonParser3 { Public Static voidWritejson (ObjectTstringfile) {Jsonserializer Serializer=NewJsonserializer (); using(StreamWriter SW =NewStreamWriter (file)) { using(Jsonwriter writer =NewJsonTextWriter (SW)) {Serializer. Serialize (writer, t); } } } Public Static voidReadjson<t> (stringFile outT obj) {Jsonserializer Serializer=NewJsonserializer (); using(StreamReader sr =NewStreamReader (file)) {obj= Jsonconvert.deserializeobject<t> (sr.) ReadToEnd (),NewJsondemoconverter ()); } } } Public Abstract classJsoncreationconverter<t>: jsonconverter {protected AbstractT Create (Type objectType, Jobject jsonobject); Public Override BOOLCanconvert (Type objectType) {return typeof(T). IsAssignableFrom (ObjectType); } Public Override ObjectReadjson (Jsonreader Reader, Type ObjectType,ObjectExistingvalue, Jsonserializer Serializer) { varJsonobject =jobject.load (reader); vartarget =Create (ObjectType, jsonobject); Serializer. Populate (Jsonobject.createreader (), target); returnTarget; } Public Override voidWritejson (Jsonwriter writer,Objectvalue, Jsonserializer serializer) { Throw Newnotimplementedexception (); } } Public classJsondemoconverter:jsoncreationconverter<demobase> { protected Overridedemobase Create (Type objectType, Jobject jsonobject) {varTypeName = jsonobject["type"]. ToString (); Switch(typeName) { Case "A": return NewDemoa (); Case "B": return Newdemob (); default:return NULL; } } }}
3. Implement the serialization of in-memory objects into Test.json in code, and then deserialize the data from Test.json to the memory object ndata:
Demodata data =NewDemodata () {demoid=1, Demos=NewList<demobase>() { NewDemoa () {id=1, name="Demoa", type="A", color="Red" }, NewDemob () {id=2, name="", type="B", size=New Double[]{Ten,Ten} } } }; Jsonparser3.writejson (data,"Test.json"); Demodata Ndata=NewDemodata (); Jsonparser3.readjson<DemoData> ("Test.json", outNdata);
4. Data in Test.json:
{ "demoid": 1, "demos": [ { "color": "Red", "id": 1, "name": "Demoa", "type": "A" }, { "size": [10.0, 10.0 ], "id": 2, "name": "", "type": "B" } ]}
5. After deserialization, the object obtained in memory Ndata
Newtonsoft.json processing of deserialization of polymorphic types