Csharp C# 解析json常用方法 您所在的位置:网站首页 解析json的方法 Csharp C# 解析json常用方法

Csharp C# 解析json常用方法

2023-12-02 14:41| 来源: 网络整理| 查看: 265

使用 Json.NET完成 .NET 对象的序列化和反序列化,以及对复杂 Json 数据的解析。

前言

最近在 C# 项目中需要使用到 Json 格式的数据,我简单上网搜索了一下,基本上有两种操作 Json 数据的方法:

使用 Windows 系统自带的类 使用第三方的包

本着“第三方包一定有比系统自带类优秀地方,否则就不会存在”的原则,再加上 JavaScriptSerializer、DataContractJsonSerializer等这些自带类库使用起来很麻烦,我毫不犹豫地就选择了在 Json 操作方面小有名气的 Json.NET。Json.NET 自己也做了与自带类库的比较,详情可以见 Json.NET vs .NET Serializers和 Json.NET vs Windows.Data.Json。

Json.NET 是一个 Newtonsoft 编写的开源类库包,你可以直接到 Github 上查看项目的源码和说明。Json.NET 提供了大量对于 Json 数据的操作方法,他们使用起来非常简单,而且执行效率很高。

.NET 对象的序列化和反序列化

 

1. 普通对象的序列化和反序列化

JsonConvert是 Json.NET 中的一个数据转换类,提供了用于 .NET 对象序列化和反序列化的方法 SerializeObject()和 DeserializeObject()。在通常情况下,我们也只需要使用这两个方法就足以完成任务了。

比如说,我们现在定义了一个学生类 Student:

class Student //学生类 { public int Id { get; set;} //学号 public string Name { get; set;} //姓名 public double[] Scores { get; set;} //成绩 }

现在我们创建一个学生类对象,并使用 JsonConvert类提供的 SerializeObject()方法将它转换到 Json 字符串(需要引入命名空间 using Newtonsoft.Json):

Student student = new Student { Id = 12883, Name = "Jim David", Scores = new double[] { 87.5, 92, 76.2 } }; string jsonStudent = JsonConvert.SerializeObject(student); //{"Id":12883,"Name":"Jim David","Scores":[87.5,92.0,76.2]}

可以看到在序列化的过程中,JsonConvert会将 .NET 对象中的变量名转换为 Json 中的“属性”,同时将变量的值复制为 Json 的“属性值”。接下来,我们尝试将 Json 字符串转换为 Student对象,使用 JsonConvert提供的 DeserializeObject()方法:

Student deserializedStudent = JsonConvert.DeserializeObject(jsonStudent); Console.WriteLine("student.Id = " + deserializedStudent.Id); //student.Id = 12883 Console.WriteLine("student.Name = " + deserializedStudent.Name); //student.Name = Jim David

可以看到,创建的学生对象 student的 Json 字符串被顺利地解析成了 Student 对象。在调用 DeserializeObject()方法进行反序列化时,最好使用带泛型参数的重载方法。

如果在调用 DeserializeObject()时不指定对象类型,JsonConvert会默认转换为 Object 对象。

2. 集合的序列化和反序列化

上面我们已经简单测试了 JsonConvert 提供的 SerializeObject()和 DeserializeObject()方法,完成了 .NET 对象的序列化和反序列化。

C# 项目中,除了自定义的类型外,集合(Collections)也是经常会使用的数据类型,包括列表、数组、字典或者我们自定义的集合类型。我们同样可以使用之前使用的 SerializeObject()和 DeserializeObject()方法来完成集合的序列化和反序列化。

为了使转换后的结果更加易读,我指定转换后的 Json 字符串带缩进。通过向 SerializeObject()方法传递进第二个参数 Formatting 实现。

Student student1 = new Student { Id = 12883, Name = "Jim David", Scores = new double[] { 87.5, 92, 76.2 } }; Student student2 = new Student { Id = 35228, Name = "Milly Smith", Scores = new double[] { 92.5, 88, 85.7 } }; List students = new List(); students.Add(student1); students.Add(student2); string jsonStudents = JsonConvert.SerializeObject(students, Formatting.Indented); //[ // { // "Id": 12883, // "Name": "Jim David", // "Scores": [ // 87.5, // 92.0, // 76.2 // ] // }, // { // "Id": 35228, // "Name": "Milly Smith", // "Scores": [ // 92.5, // 88.0, // 85.7 // ] // } //]

接下来我们对上面生成的 Json 字符串进行反序列化,解析出原有的 Student 类型列表。同样,我们需要使用带泛型参数的 DeserializeObject()方法,指定 JsonConvert 解析的目标类型。

string jsonStudentList = @"[ { 'Id': 12883, 'Name': 'Jim David', 'Scores': [ 87.5, 92.0, 76.2 ] }, { 'Id': 35228, 'Name': 'Milly Smith', 'Scores': [ 92.5, 88.0, 85.7 ] } ]"; List studentsList = JsonConvert.DeserializeObject(jsonStudentList); Console.WriteLine(studentsList.Count); //2 Student s = studentsList[0]; Console.WriteLine(s.Name); //Jim David

如果 Json 对象拥有统一类型的属性和属性值,我们还可以把 Json 字符串反序列化为 .NET 中的字典,Json 对象的“属性”和“属性值”会依次赋值给字典中的 Key 和 Value。下面我举一个简单的例子:

string json = @"{""English"":88.2,""Math"":96.9}"; Dictionary values = JsonConvert.DeserializeObject(json); Console.WriteLine(values.Count); //2 Console.WriteLine(values["Math"]); //96.9 解析复杂的 Json 字符串

 

如今大量的 Web API 为我们编写复杂程序提供了极大的方便,例如百度地图 API、图灵机器人 API等等,利用这些 Web 应用程序我们可以充分发挥云服务的优势,开发出大量有趣的应用。

Web API 通常返回 Json 或 XML 格式的检索数据,由于 Json 数据量更小,所以目前大多数情况下我们都选择返回 Json 格式的数据。

如果返回的 Json 文档很大,而我们仅仅需要其中的一小部分数据。按照之前的方法,我们必须首先定义一个与 Json 对象对应的 .NET 对象,然后反序列化,最后才能从对象中取出我们需要的数据。而有了 Json.NET,这个任务就很容易实现了,我们可以局部地解析一个 Json 对象。

下面以获取 Google 搜索结果为例,简单演示一下对复杂结构 Json 文档的解析。

string googleSearchText = @"{ 'responseData': { 'results': [ { 'GsearchResultClass': 'GwebSearch', 'unescapedUrl': 'http://en.wikipedia.org/wiki/Paris_Hilton', 'url': 'http://en.wikipedia.org/wiki/Paris_Hilton', 'visibleUrl': 'en.wikipedia.org', 'cacheUrl': 'http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org', 'title': 'Paris Hilton - Wikipedia, the free encyclopedia', 'titleNoFormatting': 'Paris Hilton - Wikipedia, the free encyclopedia', 'content': '[1] In 2006, she released her debut album...' }, { 'GsearchResultClass': 'GwebSearch', 'unescapedUrl': 'http://www.imdb.com/name/nm0385296/', 'url': 'http://www.imdb.com/name/nm0385296/', 'visibleUrl': 'www.imdb.com', 'cacheUrl': 'http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com', 'title': 'Paris Hilton', 'titleNoFormatting': 'Paris Hilton', 'content': 'Self: Zoolander. Socialite Paris Hilton...' } ], 'cursor': { 'pages': [ { 'start': '0', 'label': 1 }, { 'start': '4', 'label': 2 }, { 'start': '8', 'label': 3 }, { 'start': '12', 'label': 4 } ], 'estimatedResultCount': '59600000', 'currentPageIndex': 0, 'moreResultsUrl': 'http://www.google.com/search?oe=utf8&ie=utf8...' } }, 'responseDetails': null, 'responseStatus': 200 }";

上面就是从 Google 搜索返回的 Json 数据,我们现在需要的是 responseData属性下的 results列表中结果,而且仅仅需要结果中的 title、content和 url属性值。

public class SearchResult { public string Title { get; set; } public string Content { get; set; } public string Url { get; set; } } //将 Json 文档解析为 JObject JObject googleSearch = JObject.Parse(googleSearchText); //将获得的 Json 结果转换为列表 IList results = googleSearch["responseData"]["results"].Children().ToList(); //将 Json 结果反序列化为 .NET 对象 IList searchResults = new List(); foreach(JToken result in results) { SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); searchResults.Add(searchResult); } // Title = Paris Hilton - Wikipedia, the free encyclopedia // Content = [1] In 2006, she released her debut album... // Url = http://en.wikipedia.org/wiki/Paris_Hilton // Title = Paris Hilton // Content = Self: Zoolander. Socialite Paris Hilton... // Url = http://www.imdb.com/name/nm0385296/

可以看到,对 Json 文档的解析基本分为以下几步:

将 Json 文档转换为 JObject 对象 使用JObject[属性]获取 JObject 对象中某个属性的值(JToken 格式) 可以继续通过 JToken[属性]获取属性内部的属性值(依然为 JToken 格式) 将 JToken 格式的属性值反序列化为 .NET 对象

如果属性值为我们需要的数据对象,那么直接反序列化该对象就可以了;如果属性值为列表(比如上面 results属性的值),那么就可以调用 JToken 类的 Children()函数,获得一个可迭代的 JEnumerable 对象(用于迭代访问列表中的每一个对象),最后再依次反序列化列表中的对象。

https://json.im/jichu/csharp-json.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有