当前位置 : 主页 > 网络编程 > c#编程 >

C#中的Linq to JSON操作详解

来源:互联网 收集:自由互联 发布时间:2023-01-31
目录 一、创建JObject and JArrary实例 1、手动创建JSON 1、创建JSON对象,JObject 2、创建JSON数组,JArrary 2、使用Linq创建JSON 3、从对象创建JSON 4、解析JSON文本 5、从文件中加载JSON 二、使用Jso
目录
  • 一、创建JObject and JArrary实例
    • 1、手动创建JSON
      • 1、创建JSON对象,JObject
      • 2、创建JSON数组,JArrary
    • 2、使用Linq创建JSON
      • 3、从对象创建JSON
        • 4、解析JSON文本
          • 5、从文件中加载JSON
          • 二、使用JsonConvert.DeserializeObject反序列化JOSN片段
            • 1、数组数据
              • 2、对象格式
              • 三、修改JObject and JArrary实例
                • 四、查询JObject and JArrary实例
                  • 判断Key是否存在
                  • 五、用LINQ表达式进行查询
                    • 可以使用LINQ to JSON手动将JSON转换为. net对象。
                    • 六、使用函数SelectToken生成JToken对象可以简化查询语句
                      • 1、SelectToken
                        • 2、使用LINQ来SelectToken
                          • 3、使用JSONPath来SelectToken
                          • 七、如果Json中的Key是变化的但是结构不变,如何获取所要的内容?
                            • 八、综合实例

                              Linq to JSON是用来操作JSON对象的,可以用于快速查询、修改和创建JSON对象。

                              当JSON对象内容比较复杂,而我们仅仅需要其中的一小部分数据时,可以考虑使用Linq to JSON来读取和修改部分的数据而非反序列化全部。

                              参考:Json.NET Documentation

                              在进行Linq to JSON之前,首先要了解一下用于操作Linq to JSON的类.

                              类名说明JObject用于操作JSON对象JArray用语操作JSON数组JValue表示数组中的值JProperty表示对象中的属性,以"key/value"形式JToken用于存放Linq to JSON查询后的结果

                              一、创建JObject and JArrary实例

                              1、手动创建JSON

                              设置值和一次创建一个对象或数组可以让您完全控制,但是它比其他选项更冗长。

                              1、创建JSON对象,JObject

                              JObject staff = new JObject();
                              staff.Add(new JProperty("Name", "Jack"));
                              staff.Add(new JProperty("Age", 33));
                              staff.Add(new JProperty("Department", "Personnel Department"));
                              staff.Add(new JProperty("Leader", new JObject(new JProperty("Name", "Tom"), new JProperty("Age", 44), new JProperty("Department", "Personnel Department"))));
                              Console.WriteLine(staff.ToString());
                              //返回
                              //{
                              //  "Name": "Jack",
                              //  "Age": 33,
                              //  "Department": "Personnel Department",
                              //  "Leader": {
                              //    "Name": "Tom",
                              //    "Age": 44,
                              //    "Department": "Personnel Department"
                              //  }
                              //}

                              2、创建JSON数组,JArrary

                              JArray arr = new JArray();
                              arr.Add(new JValue(1));
                              arr.Add(new JValue(2));
                              arr.Add(new JValue(3));
                              Console.WriteLine(arr.ToString());
                              
                              //返回
                              //[
                              //  1,
                              //  2,
                              //  3
                              //]

                              2、使用Linq创建JSON

                              使用LINQ声明式地创建JSON对象,是一种从值集合创建JSON的快速方法。

                              List posts = GetPosts();
                              
                              JObject rss =
                                  new JObject(
                                      new JProperty("channel",
                                          new JObject(
                                              new JProperty("title", "James Newton-King"),
                                              new JProperty("link", "http://james.newtonking.com"),
                                              new JProperty("description", "James Newton-King's blog."),
                                              new JProperty("item",
                                                  new JArray(
                                                      from p in posts
                                                      orderby p.Title
                                                      select new JObject(
                                                          new JProperty("title", p.Title),
                                                          new JProperty("description", p.Description),
                                                          new JProperty("link", p.Link),
                                                          new JProperty("category",
                                                              new JArray(
                                                                  from c in p.Categories
                                                                  select new JValue(c)))))))));
                              
                              Console.WriteLine(rss.ToString());
                              
                              //{
                              //  "channel": {
                              //    "title": "James Newton-King",
                              //    "link": "http://james.newtonking.com",
                              //    "description": "James Newton-King\'s blog.",
                              //    "item": [
                              //      {
                              //        "title": "Json.NET 1.3 + New license + Now on CodePlex",
                              //        "description": "Announcing the release of Json.NET 1.3, the MIT license and being available on CodePlex",
                              //        "link": "http://james.newtonking.com/projects/json-net.aspx",
                              //        "category": [
                              //          "Json.NET",
                              //          "CodePlex"
                              //        ]
                              //      },
                              //      {
                              //        "title": "LINQ to JSON beta",
                              //        "description": "Announcing LINQ to JSON",
                              //        "link": "http://james.newtonking.com/projects/json-net.aspx",
                              //        "category": [
                              //          "Json.NET",
                              //          "LINQ"
                              //        ]
                              //      }
                              //    ]
                              //  }
                              //}

                              3、从对象创建JSON

                              JObject.FromObject(object o):o为要转化的对象,返回一个JObject对象

                              最后一个选项是使用FromObject()方法从非JSON类型创建JSON对象。

                              下面的示例展示了如何从匿名对象创建JSON对象,但是任何. net类型都可以与FromObject一起创建JSON。

                              var posts = new[] {
                                   new {
                                      Title="Json.NET 1.3 + New license + Now on CodePlex",
                                      Description= "Announcing the release of Json.NET 1.3, the MIT license and being available on CodePlex",
                                      Link="http://james.newtonking.com/projects/json-net.aspx",
                                      Categories=new[]{ "Json.NET","CodePlex"}
                                  },
                                   new {
                                      Title="LINQ to JSON beta",
                                      Description= "Announcing LINQ to JSON",
                                      Link="http://james.newtonking.com/projects/json-net.aspx",
                                      Categories=new[]{ "Json.NET","LINQ"}
                                  },
                              };
                              
                              
                              JObject o = JObject.FromObject(new
                              {
                                  channel = new
                                  {
                                      title = "James Newton-King",
                                      link = "http://james.newtonking.com",
                                      description = "James Newton-King's blog.",
                                      item =  //返回数组
                                      from p in posts
                                      orderby p.Title
                                      select new   
                                      {
                                          title = p.Title,
                                          description = p.Description,
                                          link = p.Link,
                                          category = p.Categories
                                      }
                                  }
                              });
                              
                              Console.WriteLine(o.ToString());
                              
                              //{
                              //  "channel": {
                              //    "title": "James Newton-King",
                              //    "link": "http://james.newtonking.com",
                              //    "description": "James Newton-King\'s blog.",
                              //    "item": [
                              //      {
                              //        "title": "Json.NET 1.3 + New license + Now on CodePlex",
                              //        "description": "Announcing the release of Json.NET 1.3, the MIT license and being available on CodePlex",
                              //        "link": "http://james.newtonking.com/projects/json-net.aspx",
                              //        "category": [
                              //          "Json.NET",
                              //          "CodePlex"
                              //        ]
                              //      },
                              //      {
                              //        "title": "LINQ to JSON beta",
                              //        "description": "Announcing LINQ to JSON",
                              //        "link": "http://james.newtonking.com/projects/json-net.aspx",
                              //        "category": [
                              //          "Json.NET",
                              //          "LINQ"
                              //        ]
                              //      }
                              //    ]
                              //  }
                              //}

                              4、解析JSON文本

                              JObject.Parse(string json):json含有JSON对象的字符串,返回为JObject对象

                              //解析JSON对象
                              string json = @"{
                                CPU: 'Intel',
                                Drives: [
                                  'DVD read/writer',
                                  '500 gigabyte hard drive'
                                ]
                              }";
                              
                              JObject o = JObject.Parse(json);
                              
                              //解析JSON数组
                              string json = @"[
                                'Small',
                                'Medium',
                                'Large'
                              ]";
                              
                              JArray a = JArray.Parse(json);

                              5、从文件中加载JSON

                              using (StreamReader reader = File.OpenText(@"c:\person.json"))
                              {
                                  JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
                                  // do stuff
                              }

                              二、使用JsonConvert.DeserializeObject反序列化JOSN片段

                              1、数组数据

                              string jsonArrayText= "[{'a','al'.'b','b1'},{'a','a2'.'b','b2'}]";
                              JArray ja = (JArray)JsonConvert.DeserializeObject(jsonArrayText); 
                              
                              string ja1a==ja[1]["a"].ToString(); 
                              //或者 
                              JObject o=(JObject)ja[1]; 
                              string ja1a=o["a"].ToString();

                              2、对象格式

                              siring jsonText= "{\"beijing\":{\"zone\":\"海淀\",\"zone_en\":\"haidian\"}";
                              
                              JObject jo =(JObject)JsonConvert.DeserializeObject(jsonArrayText);
                              string zone =jo["beijing"]["zone"].ToString();

                              三、修改JObject and JArrary实例

                              string json = @"{  
                                               'post':{  
                                                   'Title':'修改JArray和JObject',  
                                                   'Link':'http://write.blog.csdn.net',  
                                                   'Description':'这是一个修改JArray和JObject的演示案例',  
                                                   'Item':[]  
                                               }  
                                           }";
                              
                              JObject o = JObject.Parse(json);
                              JObject post = (JObject)o["post"];
                              
                              post["Title"] = ((string)post["Title"]).ToUpper();
                              post["Link"] = ((string)post["Link"]).ToUpper();
                              
                              post.Property("Description").Remove();
                              
                              post.Property("Link").AddAfterSelf(new JProperty("New", "新添加的属性"));
                              
                              JArray a = (JArray)post["Item"];
                              a.Add("修改JArray");
                              a.Add("修改JObject");

                              移除属性

                              JObject jObj = JObject.Parse(json);
                              jObj.Remove("Colleagues");//跟的是属性名称
                              Console.WriteLine(jObj.ToString());

                              四、查询JObject and JArrary实例

                              将一个值从LINQ转换为JSON的最简单方法是:使用JObject/JArray上的ItemObject索引,然后将返回的JValue转换为所需的类型。

                              string json = @"{
                                'channel': {
                                  'title': 'James Newton-King',
                                  'link': 'http://james.newtonking.com',
                                  'description': 'James Newton-King\'s blog.',
                                  'item': [
                                    {
                                      'title': 'Json.NET 1.3 + New license + Now on CodePlex',
                                      'description': 'Announcing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
                                      'link': 'http://james.newtonking.com/projects/json-net.aspx',
                                      'categories': [
                                        'Json.NET',
                                        'CodePlex'
                                      ]
                                    },
                                    {
                                      'title': 'LINQ to JSON beta',
                                      'description': 'Announcing LINQ to JSON',
                                      'link': 'http://james.newtonking.com/projects/json-net.aspx',
                                      'categories': [
                                        'Json.NET',
                                        'LINQ'
                                      ]
                                    }
                                  ]
                                }
                              }";
                              
                              JObject rss = JObject.Parse(json);
                              
                              string rssTitle = (string)rss["channel"]["title"];
                              // James Newton-King
                              
                              string itemTitle = (string)rss["channel"]["item"][0]["title"];
                              // Json.NET 1.3 + New license + Now on CodePlex
                              
                              JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
                              // ["Json.NET", "CodePlex"]
                              
                              IList<string> categoriesText = categories.Select(c => (string)c).ToList();
                              // Json.NET
                              // CodePlex

                              判断Key是否存在

                              JToken test = new JObject();
                              
                              if (test["a"] == null)
                              {
                                  Console.WriteLine("键值key不存在!");
                              }
                              
                              JObject test1 = test as JObject;
                              if (test1.Property("a") == null || test1.Property("a").ToString() == "")
                              {
                                  Console.WriteLine("键值key不存在!");
                              }

                              五、用LINQ表达式进行查询

                              也可以使用LINQ查询JObject/JArray。

                              Children()以IEnumerable的形式返回JObject/JArray的子值,然后可以使用标准的Where/OrderBy/Select LINQ操作符查询这些子值。

                              注意:

                              Children()返回token的所有子元素。如果它是一个JObject,它将返回一个要使用的属性集合,如果它是一个JArray,您将得到一个数组值的集合。

                              var postTitles =
                                  from p in rss["channel"]["item"]
                                  select (string)p["title"];
                              
                              foreach (var item in postTitles)
                              {
                                  Console.WriteLine(item);
                              }
                              
                              //LINQ to JSON beta
                              //Json.NET 1.3 + New license + Now on CodePlex
                              
                              var categories =
                                  from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values<string>()
                                  group c by c
                                  into g
                                  orderby g.Count() descending
                                  select new { Category = g.Key, Count = g.Count() };
                              
                              foreach (var c in categories)
                              {
                                  Console.WriteLine(c.Category + " - Count: " + c.Count);
                              }
                              
                              //Json.NET - Count: 2
                              //LINQ - Count: 1
                              //CodePlex - Count: 1

                              可以使用LINQ to JSON手动将JSON转换为. net对象。

                              当您处理与. net对象不匹配的JSON时,手动序列化和反序列化. net对象是很有用的。

                              string jsonText = @"{
                                'short': {
                                  'original': 'http://www.foo.com/',
                                  'short': 'krehqk',
                                  'error': {
                                    'code': 0,
                                    'msg': 'No action taken'
                                  }
                                }
                              }";
                              
                              JObject json = JObject.Parse(jsonText);
                              
                              Shortie shortie = new Shortie
                              {
                                  Original = (string)json["short"]["original"],
                                  Short = (string)json["short"]["short"],
                                  Error = new ShortieException
                                  {
                                      Code = (int)json["short"]["error"]["code"],
                                      ErrorMessage = (string)json["short"]["error"]["msg"]
                                  }
                              };
                              
                              Console.WriteLine(shortie.Original);
                              // http://www.foo.com/
                              
                              Console.WriteLine(shortie.Error.ErrorMessage);
                              // No action taken
                              
                              public class Shortie
                              {
                                  public string Original { get; set; }
                                  public string Shortened { get; set; }
                                  public string Short { get; set; }
                                  public ShortieException Error { get; set; }
                              }
                              
                              public class ShortieException
                              {
                                  public int Code { get; set; }
                                  public string ErrorMessage { get; set; }
                              }

                              六、使用函数SelectToken生成JToken对象可以简化查询语句

                              1、SelectToken

                              SelectToken是JToken上的一个方法,它将字符串路径作为子Token名,返回子Token。如果在路径的位置找不到Token,则SelectToken返回空引用。

                              该路径由属性名和按句点分隔的数组索引组成,例如manufacturer [0]. name。

                              JObject jObj = JObject.Parse(json);
                              JToken name = jObj.SelectToken("Name");
                              Console.WriteLine(name.ToString());

                              结果:Jack

                              2、使用LINQ来SelectToken

                              SelectToken支持JSONPath查询。点击这里了解更多关于JSONPath的信息。

                              查询最后一名同事的年龄

                              //将json转换为JObject
                              JObject jObj = JObject.Parse(json);
                              var age = jObj.SelectToken("Colleagues[1].Age");
                              Console.WriteLine(age.ToString());
                              
                              // manufacturer with the name 'Acme Co'
                              JToken acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");
                              
                              Console.WriteLine(acme);
                              // { "Name": "Acme Co", Products: [{ "Name": "Anvil", "Price": 50 }] }
                              
                              // name of all products priced 50 and above
                              IEnumerable pricyProducts = o.SelectTokens("$..Products[?(@.Price >= 50)].Name");
                              
                              foreach (JToken item in pricyProducts)
                              {
                                  Console.WriteLine(item);
                              }
                              // Anvil
                              // Elbow Grease

                              结果:29

                              3、使用JSONPath来SelectToken

                              SelectToken可以与标准的LINQ方法结合使用。

                              利用SelectToken来查询所有同事的名字

                              JObject jObj = JObject.Parse(json);
                              var names = jObj.SelectToken("Colleagues").Select(p => p["Name"]).ToList();
                              foreach (var name in names)
                                  Console.WriteLine(name.ToString());
                              
                              IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
                              // Lambton Quay
                              // Willis Street
                              
                              IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
                              // null
                              // Headlight Fluid
                              
                              decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));

                              结果:Tom Abel

                              七、如果Json中的Key是变化的但是结构不变,如何获取所要的内容?

                              例如:

                              {
                                  "trends": {
                                      "2013-05-31 14:31": [
                                          {
                                              "name": "我不是谁的偶像",
                                              "query": "我不是谁的偶像",
                                              "amount": "65172",
                                              "delta": "1596"
                                          },
                                          {
                                              "name": "世界无烟日",
                                              "query": "世界无烟日",
                                              "amount": "33548",
                                              "delta": "1105"
                                          }
                                      ]
                                  },
                                  "as_of": 1369981898
                              }

                              其中的"2013-05-31 14:31"是变化的key,如何获取其中的"name","query","amount","delta"等信息呢?
                              通过Linq可以很简单地做到:

                              var jObj = JObject.Parse(jsonString);
                              var tends = from c in jObj.First.First.First.First.Children()
                                          select JsonConvert.DeserializeObject(c.ToString());
                              public class Trend
                              {
                                  public string Name { get; set; }
                                  public string Query { get; set; }
                                  public string Amount { get; set; }
                                  public string Delta { get; set; }
                              }

                              八、综合实例

                              void Main()
                              {
                                  string json = "{\"Name\" : \"Jack\", \"Age\" : 34, \"Colleagues\" : [{\"Name\" : \"Tom\" , \"Age\":44},{\"Name\" : \"Abel\",\"Age\":29}] }";
                                  // 获取员工名称
                                  JObject jObject = JObject.Parse(json);
                                  var name = jObject.Value<string>("Name");
                                  
                                  Console.WriteLine(name);
                                  // 获取员工年龄
                                  JToken jToken = jObject.SelectToken("Age");
                                  Console.WriteLine(jToken.ToString());
                                  
                                  // 获取同事信息
                                  JToken jToken1 = jObject["Colleagues"];
                                  Console.WriteLine(jToken1.ToString());
                                  
                                  Console.WriteLine("=============================");
                                  // 获取员工同事的所有姓名
                                  var names = from staff in jToken1.Children()
                                              select (string)staff["Name"];
                                  // var names = jObject.SelectToken("Colleagues").Select(p => p["Name"]).ToList();
                                  foreach (var item in names)
                                  {
                                      Console.WriteLine(item);
                                  }
                                  
                                  Console.WriteLine("=============================");
                                  // 修改Jack的年龄
                                  jObject["Age"] = 99;
                                  Console.WriteLine(jObject.ToString());
                                  // 修改同事Tome的年龄
                                  jToken1[0]["Age"] = 45;
                                  Console.WriteLine(jObject.ToString());
                                  
                                  Console.WriteLine("=============================");
                                  // Abel离职了
                                  jObject["Colleagues"][1].Remove();
                                  Console.WriteLine(jObject.ToString());
                                  // 移除Jack的同事
                                  jObject.Remove("Colleagues");
                                  Console.WriteLine(jObject.ToString());
                                  
                                  Console.WriteLine("=============================");
                                  // Jack缺少部门信息
                                  jObject["Age"].Parent.AddAfterSelf(new JProperty("Department", "总裁办"));
                                  // 来了一个新员工Jerry
                                  JObject linda = new JObject(new JProperty("Name", "Linda"), new JProperty("Age", "23"));
                                  jObject.Add(new JProperty("Colleagues", new JArray() { linda }));
                                  Console.WriteLine(jObject.ToString());
                              }
                              
                              // Define other methods and classes here

                              到此这篇关于C#使用LINQ to JSON的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

                              上一篇:WPF使用DrawingContext实现二维绘图
                              下一篇:没有了
                              网友评论