JSON.docx
《JSON.docx》由会员分享,可在线阅读,更多相关《JSON.docx(20页珍藏版)》请在冰豆网上搜索。
JSON
1.什么是JSON
JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。
它基于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":
"sciencefiction"},
{"firstName":
"Tad","lastName":
"Williams","genre":
"fantasy"},
{"firstName":
"Frank","lastName":
"Peretti","genre":
"christianfiction"}
],
"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表示中国部分省市数据如下:
xmlversion="1.0"encoding="utf-8"?
>
中国
黑龙江
哈尔滨
大庆
广东
广州
深圳
珠海
台湾
台北
高雄
新疆
乌鲁木齐
用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(下载地址JsonReader,JsonWriter处理。
这种方式最通用,也最灵活,可以随时修改不爽的地方。
(1)使用JsonReader读Json字符串:
?
1
2
3
4
5
6
stringjsonText=@"{""input"":
""value"",""output"":
""result""}";
JsonReaderreader=newJsonTextReader(newStringReader(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
StringWritersw=newStringWriter();
JsonWriterwriter=newJsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("input");
writer.WriteValue("value");
writer.WritePropertyName("output");
writer.WriteValue("result");
writer.WriteEndObject();
writer.Flush();
stringjsonText=sw.GetStringBuilder().ToString();
Console.WriteLine(jsonText);
(3)使用JObject读写字符串:
?
1
2
JObjectjo=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
Projectp=newProject(){Input="stone",Output="gold"};
JsonSerializerserializer=newJsonSerializer();
StringWritersw=newStringWriter();
serializer.Serialize(newJsonTextWriter(sw),p);
Console.WriteLine(sw.GetStringBuilder().ToString());
StringReadersr=newStringReader(@"{""Input"":
""stone"",""Output"":
""gold""}");
Projectp1=(Project)serializer.Deserialize(newJsonTextReader(sr),typeof(Project));
Console.WriteLine(p1.Input+"=>"+p1.Output);
上面的代码都是基于下面这个Project类定义:
?
1
2
3
4
5
classProject
{
publicstringInput{get;set;}
publicstringOutput{get;set;}
}
此外,如果上面的JsonTextReader等类编译不过的话,说明是我们自己修改过的类,换成你们自己的相关类就可以了,不影响使用。
3.内置方式:
使用.NETFramework3.5/4.0中提供的System.Web.Script.Serialization命名空间下的JavaScriptSerializer类进行对象的序列化与反序列化,很直接。
?
1
2
3
4
5
6
7
Projectp=newProject(){Input="stone",Output="gold"};
JavaScriptSerializerserializer=newJavaScriptSerializer();
varjson=serializer.Serialize(p);
Console.WriteLine(json);
varp1=serializer.Deserialize(json);
Console.WriteLine(p1.Input+"=>"+p1.Output);
Console.WriteLine(ReferenceEquals(p,p1));
注意:
如果使用的是VS2010,则要求当前的工程的TargetFramework要改成.NetFramework4,不能使用ClientProfile。
当然这个System.Web.Extensions.dll主要是Web使用的,直接在Console工程中用感觉有点浪费资源。
此外,从最后一句也可以看到,序列化与反序列化是深拷贝的一种典型的实现方式。
更新1:
注意用System.Web.Script.Serialization的时候,序列化没问题,反序列化会将DateTime赋值成了UTC时间。
UTC时间+时区差=本地时间
6:
02+(+0800)=14:
02(北京时间)
?
1
2
3
4
5
6
7
DateTimedt=DateTime.Now;
JavaScriptSerializerserializer=newJavaScriptSerializer();
varjson=serializer.Serialize(dt);
Console.WriteLine(json);
vardt1=serializer.Deserialize(json);
Response.Write(dt1.ToString()+"
");
Response.Write(ReferenceEquals(dt,dt1));
关于UTC时间与北京时间的区别请移步:
UTC时间与北京时间差多久?
感谢@老牛吃肉提醒
4.契约方式:
使用System.Runtime.Serialization.dll提供的DataContractJsonSerializer或者JsonReaderWriterFactory实现。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Projectp=newProject(){Input="stone",Output="gold"};
DataContractJsonSerializerserializer=newDataContractJsonSerializer(p.GetType());
stringjsonText;
using(MemoryStreamstream=newMemoryStream())
{
serializer.WriteObject(stream,p);
jsonText=Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(jsonText);
}
using(MemoryStreamms=newMemoryStream(Encoding.UTF8.GetBytes(jsonText)))
{
DataContractJsonSerializerserializer1=newDataContractJsonSerializer(typeof(Project));
Projectp1=(Project)serializer1.ReadObject(ms);
Console.WriteLine(p1.Input+"=>"+p1.Output);
}
这里要注意,这里的Project类和成员要加相关的Attribute:
?
1
2
3
4
5
6
7
8
[DataContract]
classProject
{
[DataMember]
publicstringInput{get;set;}
[DataMember]
publicstringOutput{get;set;}
}
实用参考:
JSON验证工具:
JSON简明教程:
Newtonsoft.Json类库下载:
通过序列化将.net对象转换为JSON字符串
在web开发过程中,我们经常需要将从数据库中查询到的数据(一般为一个集合,列表或数组等)转换为JSON格式字符串传回客户端,这就需要进行序列化,这里用到的是JsonConvert对象的SerializeObject方法。
其语法格式为:
JsonConvert.SerializeObject(object),代码中的”object”就是要序列化的.net对象,序列化后返回的是json字符串。
比如,现在我们有一个TStudent的学生表,表中的字段和已有数据如图所示
从表中我们可以看到一共有五条数据,现在我们要从数据库中取出这些数据,然后利用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
protectedvoidPage_Load(objectsender,EventArgse)
{
using(L2SDBDataContextdb=newL2SDBDataContext())
{
ListstudentList=newList();
varquery=fromsindb.TStudents
selectnew{
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
};