JSON. NET simple instructions, json.net simple instructions

Source: Internet
Author: User

JSON. NET simple instructions, json.net simple instructions

NewtonJson is a commonly used json Parsing Library. Basically, this library is used in my project. It also has related libraries in Unity, which ensures the unification of multiple projects. At the same time, NewtonJson's serialization and deserialization interfaces are relatively simple and powerful. However, there are no pitfalls in use, so I will record some experiences for future queries.

Serialization and deserialization

Serialization and deserialization are simple. You can call related interfaces. During deserialization, you can specify generic parameters and parse them into corresponding objects. This function is much better than many lightweight JSON libraries, saves us a lot of new objects and assigning values. You can also convert the parsed object to a Dictionary without specifying the generic type. The key value is a string and the value is an object.

Var data = new JsonData () {IntValue = 1000, FValue = 3.14f, IsTrue = true, Text = "Hello World "}; // serialize json = "{\" IntValue \ ": 1000, \" Text \ ": \" Hello World \ ", \" IsTrue \ ": true, \ "FValue \": 3.14} "var json = JsonConvert. serializeObject (data); // deserialize data = JsonConvert. deserializeObject <JsonData> (json); // do not specify the generic deserialization var dict = JsonConvert. deserializeObject <Dictionary <string, object> (json );

During deserialization, the value in the json key-value pair is converted to long in a uniform manner if it is an integer type, and then converted. The floating point type is converted to Double in a uniform manner, and then converted to string, bool is directly converted. Array, list can be converted to the JArray type, and then converted to the set 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();

During deserialization, JSON. NET assigns values to key-value names and object Member names. It only recognizes names, regardless of order or even class. For example, the following two classes

class JsonData{    public int IntValue;    public string Text;    public bool 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 piece of JSON can be parsed into A or B, which has A large number of similar classes or the same classes in some projects, which is very useful in different programming sets, saves a lot of write deserialization code. Assume that Bname3 can still be parsed. It cannot be parsed because one member is added, but name3 has no value.

Specify the deserialization object

If you want to specify the JSON string deserialization object, in addition to using generic parameters, you can also use custom Converter. After inheriting JsonConverter, when receiving a json string, we can resolve it To A or B. In other words, you can specify a new function for a JSON string, but you can specify a new function for anything unrelated to the new function. The json string is only a parameter in the new method.

class DataConvert : JsonConverter{public override bool CanConvert(Type objectType){    return true;}public override object 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 constructor of a specific class.[JsonConstructor]Feature to specify the constructor used for deserialization. Here, Json. Net searches for appropriate constructor in sequence. If this feature is not specified, it searches for the default constructor first.

Class JsonData {public int IntValue; public string Text; public bool IsTrue; public float FValue; public int [] array; public List <int> list; public JsonData () {} [JsonConstructor] public JsonData (int intvalue, string text, bool istrue) {IntValue = intvalue * 2; // change Text = "We can do every thing we want here "; FValue = 0.001f; // do not change // istrue loss} data = JsonConvert. deserializeObject <JsonData> (json );

In the preceding two constructors, JSON. NET will execute the second parameter during deserialization, and the two parameter values correspond to the values in the Json string respectively. if the name of the parameter corresponds to the key value in the JSON string, but the type does not, an exception is thrown. The json key-value string value not included in the parameter will be assigned again after the construction. For example, FValue is not equal to 0.001, but 3.14.

During deserialization, json.net extracts the object string first, then new the object, and passes the json string to the constructor to assign a value. If it is a default constructor, the value is assigned after new is generated. The problem here is that if you use[JsonConstructor]If the constructor is specified and the parameter is accepted by the constructor, the value is not assigned again after the new parameter is added. If the constructor does not assign a value to the constructor, the value is lost. This is why data is always lost in our use.

Polymorphism deserialization

When deserializing a multi-state object, because the specific class may have more members than the generic parameters, If You Want To correctly deserialize the object, add valid type information to the JSON string. To inherit from SerializeBinder, the two interfaces of this class can convert the type into a string and add it to the json string. During deserialization, a new object is generated by getting the type string and using reflection.

Public class TypeNameSerializationBinder: ISerializationBinder {public TypeNameSerializationBinder () {}/// <summary> ///// </summary> /// <param name = "serializedType"> serialization type </param> /// <param name = "assemblyName"> name of the set of programs written to json </param> // <param name = "typeName"> name of the type of data written to json </param> public void BindToName (Type serializedType, out string assemblyName, out string typeName) {assemblyName = "assembly"; typeName = serializedType. fullName ;} /// <summary> ///// </summary> // <param name = "assemblyName"> name of the set read from json </param> /// <param name = "typeName"> Type name read from json </param> // <returns> </returns> public Type BindToType (string assemblyName, string typeName) {var asm = AppDomain. currentDomain. getAssemblies (); foreach (var assembly in asm) {var types = assembly. getTypes (); foreach (var type in types) {if (type. fullName = typeName) {return type ;}} return null ;}} class clsBase {public int num;} class subcls: clsBase {public string 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 is serialized correctly // 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 the "assembly" is specified for the output parameter assemblyName in the BindToName function of TypeNameSerializationBinder, the output json is the second segment, the parameter value of assemblyName in BindToType is set to "assembly". With this information, we can use reflection to correctly generate subclass objects.

BSON

Json.net also supports direct deserialization of binary json files to reduce the file size and speed up.

Improvement

After using this method, I think we can add deserialization Based on the instance object during json deserialization, first issue a new object, and then deserialize it. In this way, we can determine which members are involved in deserialization.

Related Article

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.