Json. NET use simple instructions

Source: Internet
Author: User

Newtonjson is a more commonly used JSON parsing library, and my project basically uses this library, because Unity also has its associated libraries, so to ensure the unification of a variety of projects. At the same time, the Newtonjson of the serialization and deserialization interface is relatively simple, the relative function is more powerful. However, in use is not without pits, so put some notes, for future enquiries.

Serialization and deserialization

Serialization and deserialization are simple, and the associated interfaces can be called. When deserializing, it is possible to specify generic parameters and parse them directly into corresponding objects, which is much better than many lightweight JSON libraries, saving us a lot of new objects and the steps to assign them. You can also not specify a generic, the parsed object can be converted to dictionary, the key value is a string, and value is an object.

Vardata = newJsondata(){Intvalue = 1000,Fvalue = 3.14FIsTrue =Truetext = "hello world"};//serialized JSON =  "{\" intvalue\ ": 1000,\" text\ ": \" Hello world\ ", \" istrue\ ": True,\" fvalue\ ": 3.14}" var json = jsonconvert. SerializeObject (data);//deserialization < Span class= "Hljs-keyword" >data = jsonconvert. Deserializeobject<jsondata> ( json);//Do not specify the deserialization of generics var dict =  JsonConvert. deserializeobject<dictionary<string, object>> (JSON) ; 

When deserializing, the value of the JSON key value pair, if the integer type, the unification is converted to long, and then the conversion, the floating-point type is unified into double, and then converted, String,bool directly converted. Array, the list can be converted to the Jarray type and then converted to the collection type we need.

var dict = jsonconvert.deserializeobject< Dictionary<string, object>> (JSON); var new_data = new jsondata (); New_data. Intvalue = (int) ((long) dict[ " Intvalue "]); New_data. Fvalue = (float) ((double) dict[ " Fvalue "]); New_data. Text = (string) dict[ "Text"];new_data. IsTrue = (bool) dict[ "IsTrue"];new_data.array = ((Jarray) dict[  "array"]). Values<int> (). ToArray ();                

When deserializing, JSON. NET is the assignment of the key value name and the object's member name, it only recognize the name, regardless of the order, even regardless of the class, such as by the following two classes

Class jsondata{Publicint intvalue;PublicString Text;Publicbool IsTrue; public float fvalue; public int[] array; public list<int> List;} Class jsondatab{public bool IsTrue; public int intvalue; public float fvalue; public int[] array; public list<int> List; public string Text;} var Datab = jsonconvert.deserializeobject<jsondatab> (JSON);     

The same JSON can be parsed into a and can be parsed into a B, which has a number of similar classes in some projects, or the same class, in different assemblies very useful, saving a lot of write deserialization code. Suppose Bname3, still can parse, and not because of a member and cannot parse, just Name3 no value.

Specifies the deserialized object

If we want to specify the JSON string to deserialize the object, in addition to using generic parameters, you can also use the custom converter, after inheriting Jsonconverter, when we accept the JSON string, we can choose to parse to a, or B. In other words, specify a new function for a JSON string, but new, even if nothing is completely irrelevant, and the JSON string is just a parameter to new.

Class dataconvert:jsonconverter{PublicOverrideboolCanconvert (Type objectType) {Returntrue;}PublicOverrideobject readjson (Jsonreader Reader, Type ObjectType, object Existingvalue, Jsonserializer serializer) {var data = new jsondatab (); while (reader. Read ()) {if (reader. value.tostring () = =  "Intvalue") {data. Intvalue = reader. ReadAsInt32 (). Value; }} return data;} public override void writejson (jsonwriter writer, object value, Jsonserializer serializer) {throw new NotImplementedException ();}}              

When using generic parsing, you can also use the [jsonconstructor] attribute on the constructor of a specific class to specify the constructor to use for deserialization. In this json.net it will look for the appropriate constructor in turn, and if you do not specify it, you will first find it from the default constructor.

Class jsondata{Publicint intvalue;PublicString Text;PublicBOOL IsTrue;public float fvalue; public int[] array; public list<int> List; public jsondata () {} [Jsonconstructor] public jsondata (int intvalue, Span class= "Hljs-keyword" >string text, bool istrue) {intvalue = Intvalue * 2; //change Text =  "We can do every thing we want here"; Fvalue = 0.001f; //does not change //istrue lost}}data = jsonconvert.deserializeobject< Jsondata> (JSON);               

In the above two constructors, JSON. NET executes the second parameter when deserializing, and two parameter values correspond to the values in the JSON string, if the name of the parameter corresponds to the key value in the JSON string, and the type does not correspond, an exception is thrown. The value of the JSON Key-value string that is not included in the formal parameter is assigned again after construction. For example, Fvalue would not be equal to 0.001, but 3.14.

When deserializing, Json.NET first extracts the object's string, then new out the object, and passes the part of the JSON string to the constructor for assignment, and if it is the default constructor, it is assigned after new. One problem here is that if you use [Jsonconstructor] to specify a constructor, and the function is to accept the argument, then it will not be assigned again after new, and if the parameter is not assigned within the constructor, then the value is lost. This is the reason why we always lose data when we use it.

Polymorphic deserialization

When deserializing a Polymorphic object, you need to add valid type information in the JSON string when serializing, because it is possible for a specific class to have more members than the generic parameter, and if you want to deserialize correctly. To inherit Serializebinder, the two interfaces of the class can convert a type to a string, add it to a JSON string, deserialize, and use reflection to new out a specific object by getting a string of type.

PublicClass typenameserializationbinder:iserializationbinder{PublicTypenameserializationbinder () {}///<summary>//////</summary>///<param name= "Serializedtype" > Specific types of serialization</param>///<param name= "AssemblyName" > assembly name written to JSON</param>///<param name= "TypeName" > Write JSON type name</param>PublicvoidBindtoname (Type Serializedtype,OutString AssemblyName,OutString typeName) {assemblyname ="Assembly"; TypeName = Serializedtype.fullname; }///<summary>//////</summary>///<param name= "AssemblyName" > assembly name read-in from JSON</param>///<param name= "TypeName" > Type names read in from JSON</param>///<returns></returns>Public TypeBindtotype (String AssemblyName,String typeName) {var asm = AppDomain.CurrentDomain.GetAssemblies ();foreach (VAR assemblyIn ASM) {var types = assembly. GetTypes ();foreach (var typeIn types) {if (type. FullName = = typeName) {return type; } } }ReturnNull }}class clsbase{Publicint num;} Class subcls:clsbase{Publicstring txt;} Class cls{Public clsbase M_base;}var C =New CLS ();var B =New Subcls () {num =1001, txt = "I ' m sub"};c.m_base = B;json = Jsonconvert.serializeobject (c); var _c = jsonconvert.deserializeobject<cls> (JSON); //the following code correctly serializes //json = "{\" m_base\ ": {\" $type \ ": \" Jsondotnetdemo.program+subcls\ ", \" txt\ ": \" I ' m sub\ ", \" num\ ": 1001}}" //json = "{\" M_base \ ": {\" $type \ ": \" jsondotnetdemo.program+subcls, assembly \ ", \" txt\ ": \" I ' m sub\ ", \" num\ ": 1001}}" JSON = Jsonconvert.serializeobject (c, new jsonserializersettings () {TypeNameHandling = Typenamehandling.auto, Serializationbinder = new Typenameserializationbinder ()}); _c = Jsonconvert.deserializeobject<cls> (JSON, new jsonserializersettings () { typenamehandling = Typenamehandling.auto, Serializationbinder = new Typenameserializationbinder ()});         

If you specify "assembly" for the output parameter assemblyname in the Bindtoname function of Typenameserializationbinder, the output JSON is the second paragraph, When the assemblyname parameter value at Bindtotype is "assembly", depending on the information we can use reflection to generate the subclass object correctly.

BSON

See document Json.NET also supports the direct deserialization of the binary JSON file, reduce the file volume, speed up, the specific use of the next to fill the

Improved

After using it, I think that when JSON is deserialized, it can be increased to deserialize based on the instance object, first new object, and then deserialization, so that when deserialization can be clear which members.

Json. NET use simple instructions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.