zoukankan      html  css  js  c++  java
  • 【转】C# 解析JSON方法总结

    http://blog.csdn.net/jjhua/article/details/51438317

    主要参考http://blog.csdn.NET/joyhen/article/details/24805899和http://www.cnblogs.com/yanweidie/p/4605212.html

    根据自己需求,做些测试、修改、整理。

    使用Newtonsoft.Json

    一、用JsonConvert序列化和反序列化。

    实体类不用特殊处理,正常定义属性即可,控制属性是否被序列化参照高级用法1。

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public interface IPerson  
    2. {  
    3.     string FirstName  
    4.     {  
    5.         get;  
    6.         set;  
    7.     }  
    8.     string LastName  
    9.     {  
    10.         get;  
    11.         set;  
    12.     }  
    13.     DateTime BirthDate  
    14.     {  
    15.         get;  
    16.         set;  
    17.     }  
    18. }  
    19. public class Employee : IPerson  
    20. {  
    21.     public string FirstName  
    22.     {  
    23.         get;  
    24.         set;  
    25.     }  
    26.     public string LastName  
    27.     {  
    28.         get;  
    29.         set;  
    30.     }  
    31.     public DateTime BirthDate  
    32.     {  
    33.         get;  
    34.         set;  
    35.     }  
    36.   
    37.     public string Department  
    38.     {  
    39.         get;  
    40.         set;  
    41.     }  
    42.     public string JobTitle  
    43.     {  
    44.         get;  
    45.         set;  
    46.     }  
    47.   
    48.     public string NotSerialize { get; set; }  
    49. }  
    50. public class PersonConverter : Newtonsoft.Json.Converters.CustomCreationConverter<IPerson>  
    51. {  
    52.     //重写abstract class CustomCreationConverter<T>的Create方法  
    53.     public override IPerson Create(Type objectType)  
    54.     {  
    55.         return new Employee();  
    56.     }  
    57. }  
    58. public class Product  
    59. {  
    60.     public string Name { get; set; }  
    61.     public DateTime Expiry { get; set; }  
    62.     public Decimal Price { get; set; }  
    63.     public string[] Sizes { get; set; }  
    64.     public string NotSerialize { get; set; }  
    65. }  

    1.序列化代码:

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #region 序列化 用JsonConvert  
    2. public string TestJsonSerialize()  
    3. {  
    4.     Product product = new Product();  
    5.     product.Name = "Apple";  
    6.     product.Expiry = DateTime.Now;//.AddDays(3).ToString("yyyy-MM-dd hh:mm:ss");  
    7.     product.Price = 3.99M;  
    8.   
    9.     //string json = Newtonsoft.Json.JsonConvert.SerializeObject(product); //没有缩进输出  
    10.     string json = Newtonsoft.Json.JsonConvert.SerializeObject(product, Newtonsoft.Json.Formatting.Indented);//有缩进输出  
    11.     //string json = Newtonsoft.Json.JsonConvert.SerializeObject(  
    12.     //    product,  
    13.     //    Newtonsoft.Json.Formatting.Indented,  
    14.     //    new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore }//参照高级用法中有关JsonSerializerSettings用法  
    15.     //);  
    16.     return json;  
    17. }  
    18. public string TestListJsonSerialize()  
    19. {  
    20.     Product product = new Product();  
    21.     product.Name = "Apple";  
    22.     product.Expiry = DateTime.Now;//.AddDays(3).ToString("yyyy-MM-dd hh:mm:ss");  
    23.     product.Price = 3.99M;  
    24.     product.Sizes = new string[] { "Small", "Medium", "Large" };  
    25.   
    26.     List<Product> plist = new List<Product>();  
    27.     plist.Add(product);  
    28.     plist.Add(product);  
    29.     string json = Newtonsoft.Json.JsonConvert.SerializeObject(plist, Newtonsoft.Json.Formatting.Indented);  
    30.     return json;  
    31. }  
    32. #endregion  

    2.反序列化代码:

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #region 反序列化 用JsonConvert  
    2. public string TestJsonDeserialize()  
    3. {  
    4.     string strjson = "{"Name":"Apple","Expiry":"2014-05-03 10:20:59","Price":3.99,"Sizes":["Small","Medium","Large"]}";  
    5.     Product p = Newtonsoft.Json.JsonConvert.DeserializeObject<Product>(strjson);  
    6.   
    7.     string template = @"  
    8.                             Name:{0}  
    9.                             Expiry:{1}  
    10.                             Price:{2}  
    11.                             Sizes:{3}  
    12.                         ";  
    13.   
    14.     return string.Format(template, p.Name, p.Expiry, p.Price.ToString(), string.Join(",", p.Sizes));  
    15. }  
    16. public string TestListJsonDeserialize()  
    17. {  
    18.     string strjson = "{"Name":"Apple","Expiry":"2014-05-03 10:20:59","Price":3.99,"Sizes":["Small","Medium","Large"]}";  
    19.     List<Product> plist = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Product>>(string.Format("[{0},{1}]", strjson, strjson));  
    20.   
    21.     string template = @"  
    22.                             Name:{0}  
    23.                             Expiry:{1}  
    24.                             Price:{2}  
    25.                             Sizes:{3}  
    26.                         ";  
    27.   
    28.     System.Text.StringBuilder strb = new System.Text.StringBuilder();  
    29.     plist.ForEach(x =>  
    30.         strb.AppendLine(  
    31.             string.Format(template, x.Name, x.Expiry, x.Price.ToString(), string.Join(",", x.Sizes))  
    32.         )  
    33.     );  
    34.     return strb.ToString();  
    35. }  
    36. #endregion  

    3.自定义序列化,使用实体类中定义的PersonConverter,每反序列化一次实体时会调用一次PersonConverter,还没想清楚如何用。

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #region 自定义反序列化  
    2. public string TestListCustomDeserialize()  
    3. {  
    4.     string strJson = "[ { "FirstName": "Maurice", "LastName": "Moss", "BirthDate": "1981-03-08T00:00Z", "Department": "IT", "JobTitle": "Support" }, { "FirstName": "Jen", "LastName": "Barber", "BirthDate": "1985-12-10T00:00Z", "Department": "IT", "JobTitle": "Manager" } ] ";  
    5.     List<IPerson> people = Newtonsoft.Json.JsonConvert.DeserializeObject<List<IPerson>>(strJson, new PersonConverter());  
    6.     IPerson person = people[0];  
    7.   
    8.     string template = @"  
    9.                             当前List<IPerson>[x]对象类型:{0}  
    10.                             FirstName:{1}  
    11.                             LastName:{2}  
    12.                             BirthDate:{3}  
    13.                             Department:{4}  
    14.                             JobTitle:{5}  
    15.                         ";  
    16.   
    17.     System.Text.StringBuilder strb = new System.Text.StringBuilder();  
    18.     people.ForEach(x =>  
    19.         strb.AppendLine(  
    20.             string.Format(  
    21.                 template,  
    22.                 person.GetType().ToString(),  
    23.                 x.FirstName,  
    24.                 x.LastName,  
    25.                 x.BirthDate.ToString(),  
    26.                 ((Employee)x).Department,  
    27.                 ((Employee)x).JobTitle  
    28.             )  
    29.         )  
    30.     );  
    31.     return strb.ToString();  
    32. }  
    33. #endregion  

    4、获取Json字符串中部分内容

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #region Serializing Partial JSON Fragment Example  
    2.  public class SearchResult  
    3.  {  
    4.      public string Title { get; set; }  
    5.      public string Content { get; set; }  
    6.      public string Url { get; set; }  
    7.  }  
    8.   
    9.  public string SerializingJsonFragment()  
    10.  {  
    11.      #region  
    12.      string googleSearchText = @"{  
    13.          'responseData': {  
    14.              'results': [{  
    15.                  'GsearchResultClass': 'GwebSearch',  
    16.                  'unescapedUrl': 'http://en.wikipedia.org/wiki/Paris_Hilton',  
    17.                  'url': 'http://en.wikipedia.org/wiki/Paris_Hilton',  
    18.                  'visibleUrl': 'en.wikipedia.org',  
    19.                  'cacheUrl': 'http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org',  
    20.                  'title': '<b>Paris Hilton</b> - Wikipedia, the free encyclopedia',  
    21.                  'titleNoFormatting': 'Paris Hilton - Wikipedia, the free encyclopedia',  
    22.                  'content': '[1] In 2006, she released her debut album...'  
    23.              },  
    24.              {  
    25.                  'GsearchResultClass': 'GwebSearch',  
    26.                  'unescapedUrl': 'http://www.imdb.com/name/nm0385296/',  
    27.                  'url': 'http://www.imdb.com/name/nm0385296/',  
    28.                  'visibleUrl': 'www.imdb.com',  
    29.                  'cacheUrl': 'http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com',  
    30.                  'title': '<b>Paris Hilton</b>',  
    31.                  'titleNoFormatting': 'Paris Hilton',  
    32.                  'content': 'Self: Zoolander. Socialite <b>Paris Hilton</b>...'  
    33.              }],  
    34.              'cursor': {  
    35.                  'pages': [{  
    36.                      'start': '0',  
    37.                      'label': 1  
    38.                  },  
    39.                  {  
    40.                      'start': '4',  
    41.                      'label': 2  
    42.                  },  
    43.                  {  
    44.                      'start': '8',  
    45.                      'label': 3  
    46.                  },  
    47.                  {  
    48.                      'start': '12',  
    49.                      'label': 4  
    50.                  }],  
    51.                  'estimatedResultCount': '59600000',  
    52.                  'currentPageIndex': 0,  
    53.                  'moreResultsUrl': 'http://www.google.com/search?oe=utf8&ie=utf8...'  
    54.              }  
    55.          },  
    56.          'responseDetails': null,  
    57.          'responseStatus': 200  
    58.      }";  
    59.      #endregion  
    60.   
    61.      Newtonsoft.Json.Linq.JObject googleSearch = Newtonsoft.Json.Linq.JObject.Parse(googleSearchText);  
    62.      // get JSON result objects into a list  
    63.      List<Newtonsoft.Json.Linq.JToken> listJToken = googleSearch["responseData"]["results"].Children().ToList();  
    64.      System.Text.StringBuilder strb = new System.Text.StringBuilder();  
    65.      string template = @"  
    66.                              Title:{0}  
    67.                              Content: {1}  
    68.                              Url:{2}  
    69.                          ";  
    70.      listJToken.ForEach(x =>  
    71.      {  
    72.          // serialize JSON results into .NET objects  
    73.          SearchResult searchResult = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResult>(x.ToString());  
    74.          strb.AppendLine(string.Format(template, searchResult.Title, searchResult.Content, searchResult.Url));  
    75.      });  
    76.      return strb.ToString();  
    77.  }  
    78.  
    79.  #endregion  

    输出结果

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Title:<b>Paris Hilton</b> - Wikipedia, the free encyclopedia  
    2. Content: [1] In 2006, she released her debut album...  
    3. Url:http://en.wikipedia.org/wiki/Paris_Hilton  
    4.   
    5.   
    6. Title:<b>Paris Hilton</b>  
    7. Content: Self: Zoolander. Socialite <b>Paris Hilton</b>...  
    8. Url:http://www.imdb.com/name/nm0385296/  

    5、利用Json.Linq序列化

    可以突破实体类的限制,自由组合要序列化的值

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public class Linq2Json  
    2. {  
    3.     #region GetJObject  
    4.   
    5.     //Parsing a JSON Object from text   
    6.     public Newtonsoft.Json.Linq.JObject GetJObject()  
    7.     {  
    8.         string json = @"{  
    9.                           CPU: 'Intel',  
    10.                           Drives: [  
    11.                             'DVD read/writer',  
    12.                             '500 gigabyte hard drive'  
    13.                           ]  
    14.                         }";  
    15.         Newtonsoft.Json.Linq.JObject jobject = Newtonsoft.Json.Linq.JObject.Parse(json);  
    16.         return jobject;  
    17.     }  
    18.   
    19.     /*  
    20.      * //example:=> 
    21.      *  
    22.         Linq2Json l2j = new Linq2Json(); 
    23.         Newtonsoft.Json.Linq.JObject jobject = l2j.GetJObject2(Server.MapPath("json/Person.json")); 
    24.         //return Newtonsoft.Json.JsonConvert.SerializeObject(jobject, Newtonsoft.Json.Formatting.Indented); 
    25.         return jobject.ToString(); 
    26.      */  
    27.     //Loading JSON from a file  
    28.     public Newtonsoft.Json.Linq.JObject GetJObject2(string jsonPath)  
    29.     {  
    30.         using (System.IO.StreamReader reader = System.IO.File.OpenText(jsonPath))  
    31.         {  
    32.             Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.Linq.JToken.ReadFrom(new Newtonsoft.Json.JsonTextReader(reader));  
    33.             return jobject;  
    34.         }  
    35.     }  
    36.   
    37.     //Creating JObject  
    38.     public Newtonsoft.Json.Linq.JObject GetJObject3()  
    39.     {  
    40.         List<Post> posts = GetPosts();  
    41.         Newtonsoft.Json.Linq.JObject jobject = Newtonsoft.Json.Linq.JObject.FromObject(new  
    42.         {  
    43.             channel = new  
    44.             {  
    45.                 title = "James Newton-King",  
    46.                 link = "http://james.newtonking.com",  
    47.                 description = "James Newton-King's blog.",  
    48.                 item =  
    49.                     from p in posts  
    50.                     orderby p.Title  
    51.                     select new  
    52.                     {  
    53.                         title = p.Title,  
    54.                         description = p.Description,  
    55.                         link = p.Link,  
    56.                         category = p.Category  
    57.                     }  
    58.             }  
    59.         });  
    60.   
    61.         return jobject;  
    62.     }  
    63.     /* 
    64.         { 
    65.             "channel": { 
    66.                 "title": "James Newton-King", 
    67.                 "link": "http://james.newtonking.com", 
    68.                 "description": "James Newton-King's blog.", 
    69.                 "item": [{ 
    70.                     "title": "jewron", 
    71.                     "description": "4546fds", 
    72.                     "link": "http://www.baidu.com", 
    73.                     "category": "jhgj" 
    74.                 }, 
    75.                 { 
    76.                     "title": "jofdsn", 
    77.                     "description": "mdsfan", 
    78.                     "link": "http://www.baidu.com", 
    79.                     "category": "6546" 
    80.                 }, 
    81.                 { 
    82.                     "title": "jokjn", 
    83.                     "description": "m3214an", 
    84.                     "link": "http://www.baidu.com", 
    85.                     "category": "hg425" 
    86.                 }, 
    87.                 { 
    88.                     "title": "jon", 
    89.                     "description": "man", 
    90.                     "link": "http://www.baidu.com", 
    91.                     "category": "goodman" 
    92.                 }] 
    93.             } 
    94.         } 
    95.      */  
    96.     //Creating JObject  
    97.     public Newtonsoft.Json.Linq.JObject GetJObject4()  
    98.     {  
    99.         List<Post> posts = GetPosts();  
    100.         Newtonsoft.Json.Linq.JObject rss = new Newtonsoft.Json.Linq.JObject(  
    101.                 new Newtonsoft.Json.Linq.JProperty("channel",  
    102.                     new Newtonsoft.Json.Linq.JObject(  
    103.                         new Newtonsoft.Json.Linq.JProperty("title", "James Newton-King"),  
    104.                         new Newtonsoft.Json.Linq.JProperty("link", "http://james.newtonking.com"),  
    105.                         new Newtonsoft.Json.Linq.JProperty("description", "James Newton-King's blog."),  
    106.                         new Newtonsoft.Json.Linq.JProperty("item",  
    107.                             new Newtonsoft.Json.Linq.JArray(  
    108.                                 from p in posts  
    109.                                 orderby p.Title  
    110.                                 select new Newtonsoft.Json.Linq.JObject(  
    111.                                     new Newtonsoft.Json.Linq.JProperty("title", p.Title),  
    112.                                     new Newtonsoft.Json.Linq.JProperty("description", p.Description),  
    113.                                     new Newtonsoft.Json.Linq.JProperty("link", p.Link),  
    114.                                     new Newtonsoft.Json.Linq.JProperty("category",  
    115.                                         new Newtonsoft.Json.Linq.JArray(  
    116.                                             from c in p.Category  
    117.                                             select new Newtonsoft.Json.Linq.JValue(c)  
    118.                                         )  
    119.                                     )  
    120.                                 )  
    121.                             )  
    122.                         )  
    123.                     )  
    124.                 )  
    125.             );  
    126.   
    127.         return rss;  
    128.     }  
    129.     /* 
    130.         { 
    131.             "channel": { 
    132.                 "title": "James Newton-King", 
    133.                 "link": "http://james.newtonking.com", 
    134.                 "description": "James Newton-King's blog.", 
    135.                 "item": [{ 
    136.                     "title": "jewron", 
    137.                     "description": "4546fds", 
    138.                     "link": "http://www.baidu.com", 
    139.                     "category": ["j", "h", "g", "j"] 
    140.                 }, 
    141.                 { 
    142.                     "title": "jofdsn", 
    143.                     "description": "mdsfan", 
    144.                     "link": "http://www.baidu.com", 
    145.                     "category": ["6", "5", "4", "6"] 
    146.                 }, 
    147.                 { 
    148.                     "title": "jokjn", 
    149.                     "description": "m3214an", 
    150.                     "link": "http://www.baidu.com", 
    151.                     "category": ["h", "g", "4", "2", "5"] 
    152.                 }, 
    153.                 { 
    154.                     "title": "jon", 
    155.                     "description": "man", 
    156.                     "link": "http://www.baidu.com", 
    157.                     "category": ["g", "o", "o", "d", "m", "a", "n"] 
    158.                 }] 
    159.             } 
    160.         } 
    161.      */  
    162.   
    163.     public class Post  
    164.     {  
    165.         public string Title { get; set; }  
    166.         public string Description { get; set; }  
    167.         public string Link { get; set; }  
    168.         public string Category { get; set; }  
    169.     }  
    170.     private List<Post> GetPosts()  
    171.     {  
    172.         List<Post> listp = new List<Post>()  
    173.         {  
    174.             new Post{Title="jon",Description="man",Link="http://www.baidu.com",Category="goodman"},  
    175.             new Post{Title="jofdsn",Description="mdsfan",Link="http://www.baidu.com",Category="6546"},  
    176.             new Post{Title="jewron",Description="4546fds",Link="http://www.baidu.com",Category="jhgj"},  
    177.             new Post{Title="jokjn",Description="m3214an",Link="http://www.baidu.com",Category="hg425"}  
    178.         };  
    179.         return listp;  
    180.     }  
    181.  
    182.     #endregion  
    183.  
    184.     #region GetJArray  
    185.     /* 
    186.      * //example:=> 
    187.      *  
    188.         Linq2Json l2j = new Linq2Json(); 
    189.         Newtonsoft.Json.Linq.JArray jarray = l2j.GetJArray(); 
    190.         return Newtonsoft.Json.JsonConvert.SerializeObject(jarray, Newtonsoft.Json.Formatting.Indented); 
    191.         //return jarray.ToString(); 
    192.      */  
    193.     //Parsing a JSON Array from text   
    194.     public Newtonsoft.Json.Linq.JArray GetJArray()  
    195.     {  
    196.         string json = @"[  
    197.                           'Small',  
    198.                           'Medium',  
    199.                           'Large'  
    200.                         ]";  
    201.   
    202.         Newtonsoft.Json.Linq.JArray jarray = Newtonsoft.Json.Linq.JArray.Parse(json);  
    203.         return jarray;  
    204.     }  
    205.   
    206.     //Creating JArray  
    207.     public Newtonsoft.Json.Linq.JArray GetJArray2()  
    208.     {  
    209.         Newtonsoft.Json.Linq.JArray array = new Newtonsoft.Json.Linq.JArray();  
    210.         Newtonsoft.Json.Linq.JValue text = new Newtonsoft.Json.Linq.JValue("Manual text");  
    211.         Newtonsoft.Json.Linq.JValue date = new Newtonsoft.Json.Linq.JValue(new DateTime(2000, 5, 23));  
    212.         //add to JArray  
    213.         array.Add(text);  
    214.         array.Add(date);  
    215.   
    216.         return array;  
    217.     }  
    218.  
    219.     #endregion  
    220.   
    221. }  


    使用方式

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Linq2Json l2j = new Linq2Json();  
    2. Newtonsoft.Json.Linq.JObject jarray = l2j.GetJObject4();  
    3. return jarray.ToString();  



    二、高级用法

    1.忽略某些属性

    当实体类中定义了很多属性,但序列化时只想针对某些属性时可以采用此方式。这种需求还可以细分为运行时不同时刻参与序列化属性集合不固定和固定两种情况。

    1)能解决参与序列化属性集合固定的情况

    OptOut     默认值,类中所有公有成员会被序列化,如果不想被序列化,可以用特性JsonIgnore
    OptIn     默认情况下,所有的成员不会被序列化,类中的成员只有标有特性JsonProperty的才会被序列化,当类的成员很多,但客户端仅仅需要一部分数据时,很有用

    仅需要姓名属性:

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonObject(MemberSerialization.OptIn)]  
    2. public class Person  
    3. {  
    4.     public int Age { get; set; }  
    5.   
    6.     [JsonProperty]  
    7.     public string Name { get; set; }  
    8.   
    9.     public string Sex { get; set; }  
    10.   
    11.     public bool IsMarry { get; set; }  
    12.   
    13.     public DateTime Birthday { get; set; }  
    14. }  

    输出结果

    不需要是否结婚属性

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonObject(MemberSerialization.OptOut)]  
    2. public class Person  
    3. {  
    4.     public int Age { get; set; }  
    5.   
    6.     public string Name { get; set; }  
    7.   
    8.     public string Sex { get; set; }  
    9.   
    10.     [JsonIgnore]  
    11.     public bool IsMarry { get; set; }  
    12.   
    13.     public DateTime Birthday { get; set; }  
    14. }  

    输出结果

    通过上面的例子可以看到,要实现不返回某些属性的需求很简单。1.在实体类上加上[JsonObject(MemberSerialization.OptOut)] 2.在不需要返回的属性上加上 [JsonIgnore]说明。

    2)能解决参与序列化属性集合不固定的情况

    方法1:通过设置忽略默认值属性方式。有点傻。

    方法2:继承默认的DefaultContractResolver类,传入需要输出的属性。

    2、默认值

    可以设置某个属性的默认值,然后序列化或反序列化时自动判断是否默认值,然后选择是否忽略对具有默认值的属性序列化或反序列化。

    序列化时想忽略默认值属性可以通过JsonSerializerSettings.DefaultValueHandling来确定,该值为枚举值。

    DefaultValueHandling.Ignore     序列化和反序列化时,忽略默认值
    DefaultValueHandling.Include    序列化和反序列化时,包含默认值

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [DefaultValue(10)]  
    2.  public int Age { get; set; }  
    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Person p = new Person { Age = 10, Name = "张三丰", Sex = "男", IsMarry = false, Birthday = new DateTime(1991, 1, 2) };  
    2. JsonSerializerSettings jsetting=new JsonSerializerSettings();  
    3. jsetting.DefaultValueHandling=DefaultValueHandling.Ignore;  
    4. Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));  

    输出结果

    3、空值

    与默认值类似,可以选择是否忽略对空值的属性序列化或反序列化。

    序列化时需要忽略值为NULL的属性,可以通过JsonSerializerSettings.NullValueHandling来确定,另外通过JsonSerializerSettings设置属性是对序列化过程中所有属性生效的,想单独对某一个属性生效可以使用JsonProperty,下面将分别展示两个方式。

    1)JsonSerializerSettings.NullValueHandling方式,会忽略实体中全部空值参数

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Person p = new Person { room=null,Age = 10, Name = "张三丰", Sex = "男", IsMarry = false, Birthday = new DateTime(1991, 1, 2) };  
    2.  JsonSerializerSettings jsetting=new JsonSerializerSettings();  
    3.  jsetting.NullValueHandling = NullValueHandling.Ignore;  
    4.  Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));  


    上例中不会序列化room。

    2)JsonProperty,忽略特定的属性

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonProperty(NullValueHandling=NullValueHandling.Ignore)]  
    2.  public Room room { get; set; }  

    4、支持非公共属性

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonProperty]  
    2.  private int Height { get; set; }  


    5、日期

    对于Dateime类型日期的格式化就比较麻烦了,系统自带的会格式化成iso日期标准,但是实际使用过程中大多数使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss两种格式的日期,解决办法是可以将DateTime类型改成string类型自己格式化好,然后在序列化。如果不想修改代码,可以采用下面方案实现。

          Json.Net提供了IsoDateTimeConverter日期转换这个类,可以通过JsnConverter实现相应的日期转换

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonConverter(typeof(IsoDateTimeConverter))]  
    2.  public DateTime Birthday { get; set; }  

    但是IsoDateTimeConverter日期格式不是我们想要的,我们可以继承该类实现自己的日期

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public class ChinaDateTimeConverter : DateTimeConverterBase  
    2. {  
    3.     private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };  
    4.   
    5.     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)  
    6.     {  
    7.         return dtConverter.ReadJson(reader, objectType, existingValue, serializer);  
    8.     }  
    9.   
    10.     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)  
    11.     {  
    12.         dtConverter.WriteJson(writer, value, serializer);  
    13.     }  
    14. }  


    自己实现了一个yyyy-MM-dd格式化转换类,可以看到只是初始化IsoDateTimeConverter时给的日期格式为yyyy-MM-dd即可,下面看下效果

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonConverter(typeof(ChinaDateTimeConverter))]  
    2. public DateTime Birthday { get; set; }  


    日期处理也可以通过设置全局JsonConvert.DefaultSettings,设置JsonSerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"。

    6、自定义序列化时的属性名称

    等同于DataMember中PropertyName作用。

    实体中定义的属性名可能不是自己想要的名称,但是又不能更改实体定义,这个时候可以自定义序列化字段名称。

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [JsonProperty(PropertyName = "CName")]  
    2. public string Name { get; set; }  

    7、枚举值的自定义格式化

    默认情况下对于实体里面的枚举类型系统是格式化成改枚举对应的整型数值,那如果需要格式化成枚举对应的字符怎么处理呢?

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public enum NotifyType  
    2. {  
    3.     /// <summary>  
    4.     /// Emil发送  
    5.     /// </summary>  
    6.     Mail=0,  
    7.   
    8.     /// <summary>  
    9.     /// 短信发送  
    10.     /// </summary>  
    11.     SMS=1  
    12. }  
    13. public class TestEnmu  
    14. {  
    15.     /// <summary>  
    16.     /// 消息发送类型  
    17.     /// </summary>  
    18.     [JsonConverter(typeof(StringEnumConverter))]  
    19.     public NotifyType Type { get; set; }  
    20. }  

    输出结果

    8、自定义类型转换

    默认情况下对于实体里面的Boolean系统是格式化成true或者false,对于true转成"是" false转成"否"这种需求改怎么实现了?我们可以自定义类型转换实现该需求,下面看实例

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public class BoolConvert : JsonConverter  
    2. {  
    3.     private string[] arrBString { get; set; }  
    4.   
    5.     public BoolConvert()  
    6.     {  
    7.         arrBString = "是,否".Split(',');  
    8.     }  
    9.   
    10.     /// <summary>  
    11.     /// 构造函数  
    12.     /// </summary>  
    13.     /// <param name="BooleanString">将bool值转换成的字符串值</param>  
    14.     public BoolConvert(string BooleanString)  
    15.     {  
    16.         if (string.IsNullOrEmpty(BooleanString))  
    17.         {  
    18.             throw new ArgumentNullException();  
    19.         }  
    20.         arrBString = BooleanString.Split(',');  
    21.         if (arrBString.Length != 2)  
    22.         {  
    23.             throw new ArgumentException("BooleanString格式不符合规定");  
    24.         }  
    25.     }  
    26.   
    27.   
    28.     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)  
    29.     {  
    30.         bool isNullable = IsNullableType(objectType);  
    31.         Type t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType;  
    32.   
    33.         if (reader.TokenType == JsonToken.Null)  
    34.         {  
    35.             if (!IsNullableType(objectType))  
    36.             {  
    37.                 throw new Exception(string.Format("不能转换null value to {0}.", objectType));  
    38.             }  
    39.   
    40.             return null;  
    41.         }  
    42.   
    43.         try  
    44.         {  
    45.             if (reader.TokenType == JsonToken.String)  
    46.             {  
    47.                 string boolText = reader.Value.ToString();  
    48.                 if (boolText.Equals(arrBString[0], StringComparison.OrdinalIgnoreCase))  
    49.                 {  
    50.                     return true;  
    51.                 }  
    52.                 else if (boolText.Equals(arrBString[1], StringComparison.OrdinalIgnoreCase))  
    53.                 {  
    54.                     return false;  
    55.                 }  
    56.             }  
    57.   
    58.             if (reader.TokenType == JsonToken.Integer)  
    59.             {  
    60.                 //数值  
    61.                 return Convert.ToInt32(reader.Value) == 1;  
    62.             }  
    63.         }  
    64.         catch (Exception ex)  
    65.         {  
    66.             throw new Exception(string.Format("Error converting value {0} to type '{1}'", reader.Value, objectType));  
    67.         }  
    68.         throw new Exception(string.Format("Unexpected token {0} when parsing enum", reader.TokenType));  
    69.     }  
    70.   
    71.     /// <summary>  
    72.     /// 判断是否为Bool类型  
    73.     /// </summary>  
    74.     /// <param name="objectType">类型</param>  
    75.     /// <returns>为bool类型则可以进行转换</returns>  
    76.     public override bool CanConvert(Type objectType)  
    77.     {  
    78.         return true;  
    79.     }  
    80.   
    81.   
    82.     public bool IsNullableType(Type t)  
    83.     {  
    84.         if (t == null)  
    85.         {  
    86.             throw new ArgumentNullException("t");  
    87.         }  
    88.         return (t.BaseType.FullName=="System.ValueType" && t.GetGenericTypeDefinition() == typeof(Nullable<>));  
    89.     }  
    90.   
    91.     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)  
    92.     {  
    93.         if (value == null)  
    94.         {  
    95.             writer.WriteNull();  
    96.             return;  
    97.         }  
    98.   
    99.         bool bValue = (bool)value;  
    100.   
    101.         if (bValue)  
    102.         {  
    103.             writer.WriteValue(arrBString[0]);  
    104.         }  
    105.         else  
    106.         {  
    107.             writer.WriteValue(arrBString[1]);  
    108.         }  
    109.     }  
    110. }  


    自定义了BoolConvert类型,继承自JsonConverter。构造函数参数BooleanString可以让我们自定义将true false转换成相应字符串。下面看实体里面怎么使用这个自定义转换类型

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public class Person  
    2. {  
    3.     [JsonConverter(typeof(BoolConvert))]  
    4.     public bool IsMarry { get; set; }  
    5. }  


    相应的有什么个性化的转换需求,都可以使用自定义转换类型的方式实现。

    9、全局序列化设置

    对全局缺省JsonSerializerSettings设置,省却每处都要相同设置代码的麻烦。

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();  
    2. JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>  
    3. {  
    4.  //日期类型默认格式化处理  
    5.   setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;  
    6.    setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";  
    7.   
    8.  //空值处理  
    9.    setting.NullValueHandling = NullValueHandling.Ignore;  
    10.   
    11.    //高级用法九中的Bool类型转换 设置  
    12.    setting.Converters.Add(new BoolConvert("是,否"));  
    13.   
    14.    return setting;  
    15. });  



  • 相关阅读:
    DAY67-前端入门-javascript(十三) vue03
    DAY66-前端入门-javascript(十二) vue02
    DAY65-前端入门-javascript(十一) vue01
    DAY64-前端入门-javascript(十)bootstrap
    第二篇 Flask的Response三剑客及两个小儿子
    第一篇 Flask初识
    vue+uwsgi+nginx部署luffty项目
    Nginx负载均衡
    集群概念
    Flask框架实现给视图函数增加装饰器操作示例
  • 原文地址:https://www.cnblogs.com/mimime/p/6011299.html
Copyright © 2011-2022 走看看