JSON入门资料

雨点打透心脏的1/2处 2022-08-25 09:16 251阅读 0赞

目录

1.什么是json

2.json语法规则

3.json基础结构

4.json基础示例

5.JSON和XML比较

6. .NET操作JSON

  1. 原始方式
  2. 通用方式
  3. 内置方式
  4. 契约方式

通过序列化将.net对象转换为JSON字符串

使用LINQ to JSON定制JSON数据

处理客户端提交的JSON数据

1.什么是JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

2.JSON语法规则


JSON 语法是 JavaScript 对象表示法语法的子集。

l 数据在名称/值对中

l 数据由逗号分隔

l 花括号保存对象

l 方括号保存数组

JSON 数据的书写格式是:名称/值对。

名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:

“firstName” : “John”

这很容易理解,等价于这条 JavaScript 语句:

firstName = “John”

JSON 值可以是:

l 数字(整数或浮点数)

l 字符串(在双引号中)

l 逻辑值(true 或 false)

l 数组(在方括号中)

l 对象(在花括号中)

l null

JSON在线校验格式化工具:bejson

3.JSON基础结构


JSON建构有两种结构

JSON简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。

1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。

2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 [“java”,”javascript”,”vb”,…],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

经过对象、数组2种结构就可以组合成复杂的数据结构了。

4.JSON基础示例

简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪,但是JavaScript很容易解释它,而且 JSON 可以表示比”名称 / 值对”更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

名称 / 值对

按照最简单的形式,可以用下面这样的 JSON 表示”名称 / 值对”:

{ “firstName”: “Brett” }

这个示例非常基本,而且实际上比等效的纯文本”名称 / 值对”占用更多的空间:

firstName=Brett

但是,当将多个”名称 / 值对”串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个”名称 / 值对”的 记录,比如:

{ “firstName”: “Brett”, “lastName”:”McLaughlin”, “email”: “aaaa” }

从语法方面来看,这与”名称 / 值对”相比并没有很大的优势,但是在这种情况下 JSON 更容易使用,而且可读性更好。例如,它明确地表示以上三个值都是同一记录的一部分;花括号使这些值有了某种联系。

表示数组

当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名列表。在XML中,需要许多开始标记和结束标记;如果使用典型的名称 / 值对(就像在本系列前面文章中看到的那种名称 / 值对),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstName这样的形式。

如果使用 JSON,就只需将多个带花括号的记录分组在一起:










1


2


3


4


5


6


7



{


“people”
: [


                
{
“firstName”
:
“Brett”
,
“lastName”
:
“McLaughlin”
,
“email”
:
“aaaa”
},


                
{
“firstName”
:
“Jason”
,
“lastName”
:
“Hunter”
,
“email”
:
“bbbb”
},


                
{
“firstName”
:
“Elliotte”
,
“lastName”
:
“Harold”
,
“email”
:
“cccc”
}


            
]


}

这不难理解。在这个示例中,只有一个名为 people的变量,值是包含三个条目的数组,每个条目是一个人的记录,其中包含名、姓和电子邮件地址。上面的示例演示如何用括号将记录组合成一个值。当然,可以使用相同的语法表示多个值(每个值包含多个记录):










1


2


3


4


5


6


7


8


9


10


11


12


13


14



{
“programmers”
: [


{
“firstName”
:
“Brett”
,
“lastName”
:
“McLaughlin”
,
“email”
:
“aaaa”
},


{
“firstName”
:
“Jason”
,
“lastName”
:
“Hunter”
,
“email”
:
“bbbb”
},


{
“firstName”
:
“Elliotte”
,
“lastName”
:
“Harold”
,
“email”
:
“cccc”
}


],


“authors”
: [


{
“firstName”
:
“Isaac”
,
“lastName”
:
“Asimov”
,
“genre”
:
“science fiction”
},


{
“firstName”
:
“Tad”
,
“lastName”
:
“Williams”
,
“genre”
:
“fantasy”
},


{
“firstName”
:
“Frank”
,
“lastName”
:
“Peretti”
,
“genre”
:
“christian fiction”
}


],


“musicians”
: [


{
“firstName”
:
“Eric”
,
“lastName”
:
“Clapton”
,
“instrument”
:
“guitar”
},


{
“firstName”
:
“Sergei”
,
“lastName”
:
“Rachmaninoff”
,
“instrument”
:
“piano”
}


] }

这里最值得注意的是,能够表示多个值,每个值进而包含多个值。但是还应该注意,在不同的主条目(programmers、authors 和 musicians)之间,记录中实际的名称 / 值对可以不一样。JSON 是完全动态的,允许在 JSON 结构的中间改变表示数据的方式。

在处理 JSON 格式的数据时,没有需要遵守的预定义的约束。所以,在同样的数据结构中,可以改变表示数据的方式,甚至可以以不同方式表示同一事物。

5.JSON和XML比较

可读性

JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。

可扩展性

XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,而JSON却不能扩展的。不过JSON在Javascript主场作战,可以存储Javascript复合对象,有着xml不可比拟的优势。

编码难度、解码难度(略)

实例比较

XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。

用XML表示中国部分省市数据如下:

复制代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <country>
  3. <name>中国</name>
  4. <province>
  5. <name>黑龙江</name>
  6. <cities>
  7. <city>哈尔滨</city>
  8. <city>大庆</city>
  9. </cities>
  10. </province>
  11. <province>
  12. <name>广东</name>
  13. <cities>
  14. <city>广州</city>
  15. <city>深圳</city>
  16. <city>珠海</city>
  17. </cities>
  18. </province>
  19. <province>
  20. <name>台湾</name>
  21. <cities>
  22. <city>台北</city>
  23. <city>高雄</city>
  24. </cities>
  25. </province>
  26. <province>
  27. <name>新疆</name>
  28. <cities>
  29. <city>乌鲁木齐</city>
  30. </cities>
  31. </province>
  32. </country>

复制代码

用JSON表示如下:










1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29



{


    
“name”
:
“中国”
,


    
“province”
:[


    
{


       
“name”
:
“黑龙江”
,


        
“cities”
:{


            
“city”
:[
“哈尔滨”
,
“大庆”
]


        
}


     
},


     
{


        
“name”
:
“广东”
,


        
“cities”
:{


            
“city”
:[
“广州”
,
“深圳”
,
“珠海”
]


        
}


    
},


    
{


        
“name”
:
“台湾”
,


        
“cities”
:{


            
“city”
:[
“台北”
,
“高雄”
]


        
}


    
},


    
{


        
“name”
:
“新疆”
,


        
“cities”
:{


            
“city”
:[
“乌鲁木齐”
]


        
}


    
}


]


}

6. .NET操作JSON

JSON文件读入到内存中就是字符串,.NET操作JSON就是生成与解析JSON字符串。操作JSON通常有以下几种方式:

  1. 原始方式:自己按照JSON的语法格式,写代码直接操作JSON字符串。如非必要,应该很少人会走这条路,从头再来的。

  2. 通用方式:这种方式是使用开源的类库Newtonsoft.Json(下载地址http://json.codeplex.com/)。下载后加入工程就能用。通常可以使用JObject, JsonReader, JsonWriter处理。这种方式最通用,也最灵活,可以随时修改不爽的地方。

(1)使用JsonReader读Json字符串:










1


2


3


4


5


6



string
jsonText =
@”{“”input”” : “”value””, “”output”” : “”result””}”
;


JsonReader reader =
new
JsonTextReader(
new
StringReader(jsonText));


while
(reader.Read())


{


    
Console.WriteLine(reader.TokenType +
“\t\t”
+ reader.ValueType +
“\t\t”
+ reader.Value);


}

(2)使用JsonWriter写字符串:










1


2


3


4


5


6


7


8


9


10


11



StringWriter sw =
new
StringWriter();


JsonWriter writer =
new
JsonTextWriter(sw);


writer.WriteStartObject();


writer.WritePropertyName(
“input”
);


writer.WriteValue(
“value”
);


writer.WritePropertyName(
“output”
);


writer.WriteValue(
“result”
);


writer.WriteEndObject();


writer.Flush();


string
jsonText = sw.GetStringBuilder().ToString();


Console.WriteLine(jsonText);

(3)使用JObject读写字符串:










1


2



JObject jo = JObject.Parse(jsonText);


string
[] values = jo.Properties().Select(item => item.Value.ToString()).ToArray();

(4)使用JsonSerializer读写对象(基于JsonWriter与JsonReader):










1


2


3


4


5


6


7


8



Project p =
new
Project() { Input =
“stone”
, Output =
“gold”
};


JsonSerializer serializer =
new
JsonSerializer();


StringWriter sw =
new
StringWriter();


serializer.Serialize(
new
JsonTextWriter(sw), p);


Console.WriteLine(sw.GetStringBuilder().ToString());


StringReader sr =
new
StringReader(
@”{“”Input””:””stone””, “”Output””:””gold””}”
);


Project p1 = (Project)serializer.Deserialize(
new
JsonTextReader(sr),
typeof
(Project));


Console.WriteLine(p1.Input +
“=>”
+ p1.Output);

上面的代码都是基于下面这个Project类定义:










1


2


3


4


5



class
Project


{


    
public
string
Input {
get
;
set
; }


    
public
string
Output {
get
;
set
; }


}

此外,如果上面的JsonTextReader等类编译不过的话,说明是我们自己修改过的类,换成你们自己的相关类就可以了,不影响使用。

  1. 内置方式:使用.NET Framework 3.5/4.0中提供的System.Web.Script.Serialization命名空间下的JavaScriptSerializer类进行对象的序列化与反序列化,很直接。









1


2


3


4


5


6


7



Project p =
new
Project() { Input =
“stone”
, Output =
“gold”
};


JavaScriptSerializer serializer =
new
JavaScriptSerializer();


var
json = serializer.Serialize(p);


Console.WriteLine(json);


var
p1 = serializer.Deserialize<Project>(json);


Console.WriteLine(p1.Input +
“=>”
+ p1.Output);


Console.WriteLine(ReferenceEquals(p,p1));

注意:如果使用的是VS2010,则要求当前的工程的Target Framework要改成.Net Framework 4,不能使用Client Profile。当然这个System.Web.Extensions.dll主要是Web使用的,直接在Console工程中用感觉有点浪费资源。

此外,从最后一句也可以看到,序列化与反序列化是深拷贝的一种典型的实现方式。

更新1:

注意用System.Web.Script.Serialization的时候,序列化没问题,反序列化会将DateTime赋值成了UTC时间。

UTC时间 + 时区差 = 本地时间

6:02 + (+0800) = 14:02(北京时间)

271403271235457.png










1


2


3


4


5


6


7



DateTime dt = DateTime.Now;


JavaScriptSerializer serializer =
new
JavaScriptSerializer();


var
json = serializer.Serialize(dt);


Console.WriteLine(json);


var
dt1 = serializer.Deserialize<DateTime>(json);


Response.Write(dt1.ToString()+
“<br />”
);


Response.Write(ReferenceEquals(dt, dt1));

关于UTC时间与北京时间的区别请移步:UTC时间与北京时间差多久?

感谢 @ 老牛吃肉 提醒

  1. 契约方式:使用System.Runtime.Serialization.dll提供的DataContractJsonSerializer或者 JsonReaderWriterFactory实现。









1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17



Project p =
new
Project() { Input =
“stone”
, Output =
“gold”
};


DataContractJsonSerializer serializer =
new
DataContractJsonSerializer(p.GetType());


string
jsonText;


  


using
(MemoryStream stream =
new
MemoryStream())


{


    
serializer.WriteObject(stream, p);


    
jsonText = Encoding.UTF8.GetString(stream.ToArray());


    
Console.WriteLine(jsonText);


}


 


using
(MemoryStream ms =
new
MemoryStream(Encoding.UTF8.GetBytes(jsonText)))


{


    
DataContractJsonSerializer serializer1 =
new
DataContractJsonSerializer(
typeof
(Project));


    
Project p1 = (Project)serializer1.ReadObject(ms);


    
Console.WriteLine(p1.Input +
“=>”
+ p1.Output);


}

这里要注意,这里的Project类和成员要加相关的Attribute:










1


2


3


4


5


6


7


8



[DataContract]


class
Project


{


    
[DataMember]


    
public
string
Input {
get
;
set
; }


    
[DataMember]


    
public
string
Output {
get
;
set
; }


}

实用参考:

JSON验证工具:http://jsonlint.com/

JSON简明教程:http://www.w3school.com.cn/json/

Newtonsoft.Json类库下载:http://json.codeplex.com/

通过序列化将.net对象转换为JSON字符串

在web开发过程中,我们经常需要将从数据库中查询到的数据(一般为一个集合,列表或数组等)转换为JSON格式字符串传回客户端,这就需要进行序列化,这里用到的是JsonConvert对象的SerializeObject方法。其语法格式为:JsonConvert.SerializeObject(object),代码中的”object”就是要序列化的.net对象,序列化后返回的是json字符串。

比如,现在我们有一个TStudent的学生表,表中的字段和已有数据如图所示

251455524084353.jpg251456055315862.jpg

从表中我们可以看到一共有五条数据,现在我们要从数据库中取出这些数据,然后利用JSON.NET的JsonConvert对象序列化它们为json字符串,并显示在页面上。C#代码如下










1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25



protected
void
Page_Load(
object
sender, EventArgs e)


        
{


            
using
(L2SDBDataContext db =
new
L2SDBDataContext())


            
{


                
List<Student> studentList =
new
List<Student>();


                
var
query =
from
s
in
db.TStudents


                            
select
new
{


                                
StudentID=s.StudentID,


                                
Name=s.Name,


                                
Hometown=s.Hometown,


                                
Gender=s.Gender,


                                
Brithday=s.Birthday,


                                
ClassID=s.ClassID,


                                
Weight=s.Weight,


                                
Height=s.Height,


                                
Desc=s.Desc


                            
};


                
foreach
(
var
item
in
query)


                
{


                    
Student student =
new
Student { StudentID=item.StudentID,Name=item.Name,Hometown=item.Hometown,Gender=item.Gender,Brithday=item.Brithday,ClassID=item.ClassID,Weight=item.Weight,Height=item.Height,Desc=item.Desc};


                    
studentList.Add(student);


                
}


                
lbMsg.InnerText = JsonConvert.SerializeObject(studentList);


            
}


        
}

输出结果:

251456288651394.jpg

从图中我们可以看到,数据库中的5条记录全部取出来并转化为json字符串了。

使用LINQ to JSON定制JSON数据

使用JsonConvert对象的SerializeObject只是简单地将一个list或集合转换为json字符串。但是,有的时候我们的前端框架比如ExtJs对服务端返回的数据格式是有一定要求的,比如下面的数据格式,这时就需要用到JSON.NET的LINQ to JSON,LINQ to JSON的作用就是根据需要的格式来定制json数据。

比如经常用在分页的json格式如代码:










1


2


3


4


5


6



{


    
“total”
: 5,
//记录总数


    
“rows”
:[


        
//json格式的数据列表


    
]


}

使用LINQ to JSON前,需要引用Newtonsoft.Json的dll和using Newtonsoft.Json.Linq的命名空间。LINQ to JSON主要使用到JObject, JArray, JProperty和JValue这四个对象,JObject用来生成一个JSON对象,简单来说就是生成”{}”,JArray用来生成一个JSON数组,也就是”[]”,JProperty用来生成一个JSON数据,格式为key/value的值,而JValue则直接生成一个JSON值。下面我们就用LINQ to JSON返回上面分页格式的数据。代码如下:










1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42



protected
void
Page_Load(
object
sender, EventArgs e)


        
{


            
using
(L2SDBDataContext db =
new
L2SDBDataContext())


            
{


                
//从数据库中取出数据并放到列表list中


                
List<Student> studentList =
new
List<Student>();


                
var
query =
from
s
in
db.TStudents


                            
select
new


                            
{


                                
StudentID = s.StudentID,


                                
Name = s.Name,


                                
Hometown = s.Hometown,


                                
Gender = s.Gender,


                                
Brithday = s.Birthday,


                                
ClassID = s.ClassID,


                                
Weight = s.Weight,


                                
Height = s.Height,


                                
Desc = s.Desc


                            
};


                
foreach
(
var
item
in
query)


                
{


                    
Student student =
new
Student { StudentID = item.StudentID, Name = item.Name, Hometown = item.Hometown, Gender = item.Gender, Brithday = item.Brithday, ClassID = item.ClassID, Weight = item.Weight, Height = item.Height, Desc = item.Desc };


                    
studentList.Add(student);


                
}


  


                
//基于创建的list使用LINQ to JSON创建期望格式的JSON数据


                
lbMsg.InnerText =
new
JObject(


                        
new
JProperty(
“total”
,studentList.Count),


                        
new
JProperty(
“rows”
,


                                
new
JArray(


                                        
//使用LINQ to JSON可直接在select语句中生成JSON数据对象,无须其它转换过程


                                        
from
p
in
studentList


                                        
select
new
JObject(


                                                
new
JProperty(
“studentID”
,p.StudentID),


                                                
new
JProperty(
“name”
,p.Name),


                                                
new
JProperty(
“homeTown”
,p.Hometown)


                                            
)


                                    
)


                            
)


                    
).ToString();


            
}


        
}

输出结果为:

251456565572185.jpg

处理客户端提交的JSON数据

客户端提交过来的数据一般都是json字符串,有了更好地进行操作(面向对象的方式),所以我们一般都会想办法将json字符串转换为json对象。例如客户端提交了以下数组格式json字符串。










1


2


3


4


5



[


    
{StudentID:
“100”
,Name:
“aaa”
,Hometown:
“china”
},


    
{StudentID:
“101”
,Name:
“bbb”
,Hometown:
“us”
},


    
{StudentID:
“102”
,Name:
“ccc”
,Hometown:
“england”
}


]

在服务端就可以使用JObject或JArray的Parse方法轻松地将json字符串转换为json对象,然后通过对象的方式提取数据。下面是服务端代码。










1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19



protected
void
Page_Load(
object
sender, EventArgs e)


        
{


            
string
inputJsonString =
@”


                
[


                    
{StudentID:’100’,Name:’aaa’,Hometown:’china’},


                    
{StudentID:’101’,Name:’bbb’,Hometown:’us’},


                    
{StudentID:’102’,Name:’ccc’,Hometown:’england’}


                
]”
;


            
JArray jsonObj = JArray.Parse(inputJsonString);


            
string
message =
@”<table border=’1’>


                    
<tr><td width=’80’>StudentID</td><td width=’100’>Name</td><td width=’100’>Hometown</td></tr>”
;


            
string
tpl =
“<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>”
;


            
foreach
(JObject jObject
in
jsonObj)


            
{


                
message += String.Format(tpl, jObject[
“StudentID”
], jObject[
“Name”
],jObject[
“Hometown”
]);


            
}


            
message +=
“</table>”
;


            
lbMsg.InnerHtml = message;


        
}

输出结果:

251457095429652.jpg

当然,服务端除了使用LINQ to JSON来转换json字符串外,也可以使用JsonConvert的DeserializeObject方法。如下面代码实现上面同样的功能。










1


2


3


4


5



List<Student> studentList = JsonConvert.DeserializeObject<List<Student>>(inputJsonString);
//注意这里必须为List<Student>类型,因为客户端提交的是一个数组json


            
foreach
(Student student
in
studentList)


            
{


                
message += String.Format(tpl, student.StudentID, student.Name,student.Hometown);


            
}

总结:

在客户端,读写json对象可以使用”.”操作符或”[“key”]”,json字符串转换为json对象使用eval()函数。

在服务端,由.net对象转换json字符串优先使用JsonConvert对象的SerializeObject方法,定制输出json字符串使用LINQ to JSON。由json字符串转换为.net对象优先使用JsonConvert对象的DeserializeObject方法,然后也可以使用LINQ to JSON。

转自:http://www.cnblogs.com/zxlovenet/p/3566802.html

作者:初行
来源:zxlovenet.cnblogs.com

参考来源:

百度百科

http://www.cnblogs.com/dxy1982/archive/2012/02/20/2355619.html

http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html

发表评论

表情:
评论列表 (有 0 条评论,251人围观)

还没有评论,来说两句吧...

相关阅读

    相关 [Jenkins]Jenkins入门资料

    Jenkins是开源自动化服务器,可以实现自动构建、自动部署等功能。可以把Jenkins理解成一个执行的流程,如先下载代码,构建代码,部署应用,重启服务器等等一系列的动作。具体

    相关 json入门

    在异步应用程序中发送和接收信息时,可以选择以纯文本和 XML 作为数据格式。[掌握 Ajax][Ajax] 的这一期讨论另一种有用的数据格式JavaScript Object