Mobile applications pay attention to speed, good experience. Just a project on hand. The server-side interface has performance issues that need to be optimized. In multiple modifications to the interface, the entity adds many fields for intermediate calculations or storage, And then finally serialized return data with Newtonsoft.json, after analyzing a simple list interface each row of data returned 16 fields, but the mobile app side only used 7 of the fields, the remaining 9 fields of data are all redundant, if the interface return data is 40K size, that is, about 20K of data is Invalid data, 20K download under 3G network almost need 1s, do not return invalid data at least can save 1s time, greatly improve the user experience. This article will introduce some of the advanced usage of Newtonsoft.json, which can be modified with very little code to solve the above problems.
Read Catalogue
- Newtonsoft.json Introduction
- Basic usage
- Advanced usage
- Summarize
Back to top Newtonsoft.json introduction
When doing development, many data exchanges are transmitted in JSON format. When using Json, we often involve the use of several serialized objects:datacontractjsonserializer,javascriptserializer , and json.net that is Newtonsoft.json. Most people will choose performance and versatility good json.net, this is not Microsoft's class library, but an open source world-class JSON Operation class Library, from the following performance comparison can see one of its performance advantages.
Complete API introduction, easy to use
Go back to the top of basic usage
Json.NET is a support for serializing and deserializing the datatable,dataset,entity framework and Entity. The following are examples of serialization and deserialization, respectively.
DataTable:
Serialize DataTable DataTable dt = new DataTable (); Dt. Columns.Add ("Age", Type.GetType ("System.Int32")); Dt. Columns.Add ("Name", Type.GetType ("System.String")); Dt. Columns.Add ("Sex", Type.GetType ("System.String")); Dt. Columns.Add ("Ismarry", Type.GetType ("System.Boolean")); for (int i = 0; i < 4; i++) { DataRow dr = dt. NewRow (); Dr["age"] = i + 1; dr["name"] = "name" + i; dr["Sex"] = i% 2 = = 0? "Male": "Female"; dr["Ismarry"] = i% 2 > 0? True:false; Dt. Rows.Add (DR); } Console.WriteLine (jsonconvert.serializeobject (DT));
Use the string above to deserialize
String json = jsonconvert.serializeobject (DT); Dt=jsonconvert.deserializeobject<datatable> (JSON); foreach (DataRow dr in Dt. Rows) {Console.WriteLine ("{0}\t{1}\t{2}\t{3}\t", dr[0], dr[1], dr[2], dr[3]);}
Entity serialization, like a DataTable, does not introduce too much.
Back to top advanced usage
1. Ignore certain properties
2. Handling of default values
3. Handling of NULL values
4. Support for non-public members
5. Date Processing
6. Custom serialized Field names
7. Dynamically determines whether a property is serialized
8. Custom formatting problems with enumeration values
9. Custom type Conversions
10. Global Serialization Settings
I. Ignoring certain properties
Similar to the interface optimizations described at the beginning of this question, some attributes in the entity do not need to be serialized back, which can be used. The Json.NET serialization mode is introduced first: OptOut and OptIn
OptOut |
Default value, all public members of the class are serialized, and if you do not want to be serialized, you can use the attribute Jsonignore |
OptIn |
By default, all members will not be serialized, and members of the class will only be serialized if they have attribute jsonproperty, which is useful when the class has a large number of members, but only a subset of the data is needed by the client. |
Only name attributes required
[Jsonobject (Memberserialization.optin)] public class person {public int age {get; set;} [Jsonproperty] public string Name {get; set;} public string Sex {get; set;} public bool Ismarry {get; set;} Public DateTime Birthday {get; set;} }
Do not need to be married attribute
[Jsonobject (memberserialization.optout)] public class person {public int age {get; set;} public string Name {get; set;} public string Sex {get; set;} [Jsonignore] public bool Ismarry {get; set;} Public DateTime Birthday {get; set;} }
As you can see from the example above, it is easy to implement a requirement that does not return certain properties. 1. Add [Jsonobject (Memberserialization.optout)] to the entity Class 2. Add the [Jsonignore] description on the attribute that does not need to be returned.
Two. Default value handling
When serializing to ignore the default Value property can be determined by jsonserializersettings.defaultvaluehandling, the value is an enumeration value
Defaultvaluehandling.ignore |
Ignore default values when serializing and deserializing |
Defaultvaluehandling.include |
Include default values when serializing and deserializing |
[DefaultValue] public int age {get; set;}
Person p = new Man {age = ten, Name = "Zhang Sanfeng", Sex = "male", Ismarry = False, Birthday = new DateTime (1991, 1, 2)}; Jsonserializersettings jsetting=new jsonserializersettings (); Jsetting. Defaultvaluehandling=defaultvaluehandling.ignore; Console.WriteLine (Jsonconvert.serializeobject (P, formatting.indented, jsetting));
The final result is as follows:
Three. Handling of NULL values
A null-valued property needs to be ignored when serializing, Can be determined by jsonserializersettings.nullvaluehandling, and the Jsonserializersettings setting property is in effect for all properties in the serialization process, and you can use it if you want to take effect on a property individually Jsonproperty , the following will show two different ways
1.JsonSerializerSettings
Person p = new Person {room=null,age = ten, Name = "Zhang Sanfeng", Sex = "male", Ismarry = False, Birthday = new DateTime (1991, 1, 2) }; Jsonserializersettings jsetting=new jsonserializersettings (); Jsetting. nullvaluehandling = Nullvaluehandling.ignore; Console.WriteLine (Jsonconvert.serializeobject (P, formatting.indented, jsetting));
2.JsonProperty
Through the Jsonproperty property set method, you can implement a particular property to deal with the requirements, such as default value processing, NULL processing, custom attribute name processing, format processing. The above null-value processing implementation
[Jsonproperty (Nullvaluehandling=nullvaluehandling.ignore)] public guest (n.);
Four. Support for non-public members
The default is to handle public members when serializing, and if you need to process non-public members, add the attribute "Jsonproperty" to the member
[Jsonproperty] private int Height {get; set;}
Five. Date processing
For the Dateime type date format is more troublesome, the system will be formatted into the ISO date standard, but the actual use of most of the use of the process may be yyyy-mm-dd or YYYY-MM-DD HH:mm:ss Two formats of the date, The workaround is to change the datetime type to a string type itself, and then serialize it. If you do not want to modify the code, you can implement the following scenario.
Json.NET provides a isodatetimeconverter date conversion class that can be jsnconverter to achieve the appropriate date conversion
[Jsonconverter (typeof (Isodatetimeconverter))] Public DateTime Birthday {get; set;}
But the Isodatetimeconverter date format is not what we want, we can inherit the class to implement its own date
public class Chinadatetimeconverter:datetimeconverterbase { private static Isodatetimeconverter Dtconverter = new Isodatetimeconverter {DateTimeFormat = "yyyy-mm-dd"}; public override Object Readjson (Jsonreader reader, Type objectType, Object Existingvalue, Jsonserializer serializer) { return Dtconverter.readjson (reader, ObjectType, existingvalue, serializer); } public override void Writejson (Jsonwriter writer, object value, Jsonserializer serializer) { Dtconverter.writejson (writer, value, serializer); } }
The implementation of a YYYY-MM-DD format conversion class, you can see just initialize isodatetimeconverter when the date format is YYYY-MM-DD, the following look at the effect
[Jsonconverter (typeof (Chinadatetimeconverter))]public DateTime Birthday {get; set;}
Different conversion classes can be implemented according to your needs
Six. Custom serialized field names
the attribute name defined in the entity may not be the name you want, but you cannot change the entity definition, and you can customize the serialized field name at this time.
[Jsonproperty (propertyname = "CName")] public string Name {get; set;}
Seven. Dynamically determines whether a property is serialized
This is to achieve a special increase in the demand for the @ Rice, according to some scenarios, may be a scene output a,b,c three properties, B scene output e,f properties. Although this requirement does not necessarily exist in practice, json.net can still support this feature.
Inherit the default Defaultcontractresolver class, passing in properties that require output
Rewrite modified a bit, in most cases should be to exclude the field is less than the field to be retained, in order to facilitate writing here modified the constructor to join retain to indicate whether props is required to keep the field or to exclude the field
public class Limitpropscontractresolver:defaultcontractresolver {string[] props = null; BOOL retain; <summary>///constructor////</summary>//<param name= "props" > Incoming attribute array </param> <param name= "Retain" >true: Indicates that props is a field that needs to be persisted false: Indicates props is the field to exclude </param> public Limitpropsco Ntractresolver (string[] props, bool retain=true) {//Specify the manifest to serialize the attribute this.props = props; This.retain = retain; } protected override ilist<jsonproperty> Createproperties (type type, Memberserialization Memberseriali zation) {ilist<jsonproperty> list = base. Createproperties (type, memberserialization); Keep only the list of properties listed with the return list. Where (P = = {if (retain) {return props. Contains (P.propertyname); } else { Return!props. Contains (P.propertyname); } }). ToList (); }
public int Age {get; set;} [Jsonignore] public bool Ismarry {get; set;} public string Sex {get; set;}
Jsonserializersettings jsetting=new jsonserializersettings (); Jsetting. Contractresolver = new Limitpropscontractresolver (new string[] {"Age", "Ismarry"}); Console.WriteLine (Jsonconvert.serializeobject (P, formatting.indented, jsetting));
Using a custom parsing class, only output "age", "Ismarry" two properties, see the final result. Only the Age property is output, why the Ismarry attribute is not output, because it is labeled Jsonignore
See the above results to achieve the PC-side serialization part, mobile phone side serialization Another part is very simple, we changed the code to implement
string[] propnames = null; if (P.age >) { propnames = new string[] {"Age", "Ismarry"}; } else { propnames = new string[] {"Age", "Sex"}; } Jsetting. Contractresolver = new Limitpropscontractresolver (propnames); Console.WriteLine (Jsonconvert.serializeobject (P, formatting.indented, jsetting));
Eight. Custom formatting problems with enumeration values
By default, the enumeration type system in the entity is formatted to change the integer value of the enumeration, so what if you need to format the corresponding character of the enumeration? Newtonsoft.json also help us think of this point, see the example below
public enum Notifytype {//<summary>// Emil Send// </summary> mail=0, /// <summary>//SMS Send/// </summary> sms=1 } public class Testenmu { // <summary>//// message Send type/// </summary> public notifytype type {get; set;} } Jsonconvert.serializeobject (New Testenmu ());
Output: Now retrofit, Output "Type": "Mail"
public class Testenmu {///<summary>///// </summary> [jsonconverter (typeof (Stringenumconverter))] Public Notifytype Type {get; set;} }
The other is the same, with the type attribute added Jsonconverter (typeof (Stringenumconverter)) to convert the enumeration value to the corresponding string, The Stringenumconverter is the Newtonsoft.json built-in conversion type, which results in the final output
Nine. Custom type conversions
By default, the Boolean system inside the entity is formatted as TRUE or FALSE, and for true to turn "yes" false to "no" how does this need to be changed? We can implement this requirement by customizing the type conversion, see the example below
public class Boolconvert:jsonconverter {private string[] arrbstring {get; set;} Public Boolconvert () {arrbstring = "Yes, no". Split (', '); }///<summary>//constructor///</summary>//<param name= "booleanstring" > Will Boo The L value is converted to a string value of </param> public Boolconvert (string booleanstring) {if (string. IsNullOrEmpty (booleanstring)) {throw new ArgumentNullException (); } arrbstring = Booleanstring.split (', '); if (arrbstring.length! = 2) {throw new ArgumentException ("booleanstring format does not meet the requirements"); }} public override Object Readjson (Jsonreader reader, Type objectType, Object Existingvalue, Jsonserializer Serializer) {bool isnullable = Isnullabletype (ObjectType); Type t = isnullable? Nullable.getunderlyingtype (ObjectType): ObjectType; if (readEr. Tokentype = = jsontoken.null) {if (! Isnullabletype (ObjectType)) {throw new Exception (string. Format ("Cannot convert null value to {0}.", ObjectType)); } return null; } try {if (reader. Tokentype = = jsontoken.string) {String booltext = reader. Value.tostring (); if (Booltext.equals (arrbstring[0], stringcomparison.ordinalignorecase)) {return True } else if (Booltext.equals (arrbstring[1], stringcomparison.ordinalignorecase)) { return false; }} if (reader. Tokentype = = Jsontoken.integer) {//Value return Convert.ToInt32 (reader). Value) = = 1; }} catch (Exception ex) {throw new Exception (string. Format ("Error converting value {0} to type ' {1} '", Reader. Value, ObjectType)); } Throw new Exception (string. Format ("unexpected token {0} when parsing enum", reader. Tokentype)); }//<summary>//To determine if bool type///</summary>//<param name= "ObjectType" > Type </param>/////<returns> bool type can be converted </returns> public override bool Canconvert (type Obje Cttype) {return true; } public bool Isnullabletype (Type t) {if (t = = null) {throw new Argum Entnullexception ("T"); } return (t.basetype.fullname== "System.ValueType" && t.getgenerictypedefinition () = = typeof (Nullable< ;>)); public override void Writejson (Jsonwriter writer, object value, Jsonserializer serializer) {if (value = = null) {writer. Writenull (); Return } bool BValue = (bool) value; if (BValue) {writer. WriteValue (Arrbstring[0]); } else {writer. WriteValue (arrbstring[1]); } } }
Custom Boolconvert type, inherited from Jsonconverter. The constructor parameter booleanstring allows us to customize to convert true false to the appropriate string. Here's how the entity uses this custom conversion type
public class person { [Jsonconverter (typeof (Boolconvert))] public bool Ismarry {get; set;} }
‘
There are individual conversion requirements that can be implemented using custom conversion types.
10. Global Serialization Settings
The article begins with the question of how the Null value field does not return, and the corresponding solution using jsetting is also given in the advanced usage. nullvaluehandling = Nullvaluehandling.ignore; To set no null value to be returned. There's a problem here, and every serialization that doesn't want to return a null value needs to be set. Can you set some default values for serialization? The following answers
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings (); Jsonconvert.defaultsettings = new Func<jsonserializersettings> (() = {
Date type default format processing setting. dateformathandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; Setting. dateformatstring = "Yyyy-mm-dd HH:mm:ss";
Null processing setting. nullvaluehandling = Nullvaluehandling.ignore;
Advanced usage nine of the bool type conversion settings setting. Converters.add (New Boolconvert ("Yes, no")); return setting; });
After this setting, the future use of the serialization of the place does not need to be set up separately, the personal favorite set is the empty value processing this piece.
Enumeration value Serialization problem
By default, the enumeration type system in the entity is formatted to change the integer value of the enumeration, so what if you need to format the corresponding character of the enumeration? Newtonsoft.json also help us think of this point, see the example below
public enum Notifytype {//<summary>// Emil Send// </summary> mail=0, /// <summary>//SMS Send/// </summary> sms=1 } public class Testenmu { // <summary>//// message Send type/// </summary> public notifytype type {get; set;} } Jsonconvert.serializeobject (New Testenmu ());
Output: Now retrofit, Output "Type": "Mail"
public class Testenmu {///<summary>///// </summary> [jsonconverter (typeof (Stringenumconverter))] Public Notifytype Type {get; set;} }
The other is the same, with the type attribute added Jsonconverter (typeof (Stringenumconverter)) to convert the enumeration value to the corresponding string, The Stringenumconverter is the Newtonsoft.json built-in conversion type, which results in the final output
Back to top global settings
The global parameter setting function is my favorite feature, now I do the MVC project, I will first set the null value processing, reduce unnecessary traffic loss. At the beginning of the previous article, the initial study of Newtonsoft.json was started from the mobile project, and the Useless field null field was not returned.
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings (); Jsonconvert.defaultsettings = new Func<jsonserializersettings> (() = {//Date type default format processing setting. dateformathandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; Setting. dateformatstring = "Yyyy-mm-dd HH:mm:ss"; Null processing setting. nullvaluehandling = Nullvaluehandling.ignore;return setting; });
Back to top of the summary
Newtonsoft.json Serialization library for us to think of a lot of features, but also implemented a lot of features, in addition to the above mentioned several advanced usage, there are other special usage, you can go to the official website to study. Of course, my favorite feature here is the one that ignores the partial attribute serialization, and the small code churn realizes the optimization of the interface and improves the user experience.
From: http://www.cnblogs.com/yanweidie/p/4605212.html
Newtonsoft.json Advanced Usage