JSON资料整理

 

目录

1.什么是json

2.json语法规则

3.json基础结构

4.json基础示例

5.JSON和XML比较

6. .NET操作JSON

原始方式

通用方式

内置方式

契约方式

通过序列化将.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表示中国部分省市数据如下:

<?xml version="1.0" encoding="utf-8"?>
<country>
    <name>中国</name>
    <province>
        <name>黑龙江</name>
        <cities>
            <city>哈尔滨</city>
            <city>大庆</city>
        </cities>
    </province>
    <province>
        <name>广东</name>
        <cities>
            <city>广州</city>
            <city>深圳</city>
            <city>珠海</city>
        </cities>
    </province>
    <province>
        <name>台湾</name>
        <cities>
            <city>台北</city>
            <city>高雄</city>
        </cities>
    </province>
    <province>
        <name>新疆</name>
        <cities>
            <city>乌鲁木齐</city>
        </cities>
    </province>
</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等类编译不过的话,说明是我们自己修改过的类,换成你们自己的相关类就可以了,不影响使用。

3. 内置方式:使用.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(北京时间)


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时间与北京时间差多久?

4. 契约方式:使用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的学生表,表中的字段和已有数据如图所示

从表中我们可以看到一共有五条数据,现在我们要从数据库中取出这些数据,然后利用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);

            }

        }

输出结果:

从图中我们可以看到,数据库中的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();

            }

        }

输出结果为:

处理客户端提交的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;

        }

输出结果:

当然,服务端除了使用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/dxy1982/archive/2012/02/20/2355619.html

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

时间: 2024-10-13 23:47:11

JSON资料整理的相关文章

JS搞基指南----延迟对象入门提高资料整理

原文:JS搞基指南----延迟对象入门提高资料整理 JavaScript的Deferred是比较高大上的东西,  主要的应用还是主ajax的应用,  因为JS和nodeJS这几年的普及,  前端的代码越来越多,  各种回调套回调再套回调实在太让人崩溃, 所以就从后端拖了一个延迟对象这货, 用来解决回调地狱这个问题 .  我们使用ajax的时候多数都是为ajax添加回调 ,然后异步向服务器发送请求, 比如如下原生的XHR代码: <!DOCTYPE html PUBLIC "-//W3C//D

iOS-- (转)学习资料整理 推荐必读!!!

iOS 学习资料整理 2015-01-12 11:31 420人阅读 评论(0) 收藏 举报  分类: 其它(50)  目录(?)[+] 这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的目前所处的位置. 该文档会持续更新, 同时也欢迎更多具有丰富经验的 iOS 开发者将自己的常用的一些工具, 学习资料, 学习心得等分享上来, 我将定期筛选合并,

【超齐全】iOS 学习资料整理

好赶货,收藏.原文iOS 学习资料整理 这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的目前所处的位置. 该文档会持续更新, 同时也欢迎更多具有丰富经验的 iOS 开发者将自己的常用的一些工具, 学习资料, 学习心得等分享上来, 我将定期筛选合并, 文档尚有一些不完善之处, 也请不吝指出, 感谢您对 iOS 所做的贡献, 让我们一起把国内的 iO

不错的Nodejs或者JS资料整理

资料整理 Node.js官网 - 可以下载到Node.js以及查看官方文档 Node.js教程 - 菜鸟教程网 Javascript模块化编程(一):模块的写法 - 阮一峰老师的日志,很值得看 CommonJS官网 requireJS官网 - AMD规范在其中 seaJS官网 - CMD规范在其中 request模块 cheerio模块

iOS开发资料整理

Please help me contribute to this list, for non-experience iOS developers or someone who need a come-in-handy library list to refer or to use in their projects. Fork, edit and send a PR are all things you can do! Table of Contents UI Component// UI组件

iOS 开发学习资料整理(持续更新)

"如果说我看得比别人远些,那是因为我站在巨人们的肩膀上." ---牛顿 iOS及Mac开源项目和学习资料[超级全面] http://www.kancloud.cn/digest/ios-mac-study/84557 iOS 学习资料整理 https://segmentfault.com/a/1190000002473595#articleHeader16 iOS.mac开源项目及库 https://github.com/Tim9Liu9/TimLiu-iOS Swift语言 http

mql4资料整理

mql4资料整理 开发工具和SDK相关 http://codebase.mql4.com/cn/在该页面的左边有MeteTrader 5 和 页面 MT4的开发工具下载 开发资料1. 参考文档http://docs.mql4.com/cn/ 2.其它相关bloghttp://www.cnblogs.com/niniwzw/category/212678.htmlhttp://www.cnblogs.com/niniwzw/tag/MQL4/3.其它相关资源学习列表http://search.do

Doxygen资料整理

@author          作者@brief             摘要@version         版本号@date             日期@file                文件名,可以默认为空,DoxyGen会自己加@class             类名@param           函数参数@return           函数返回值描述@exception      函数抛异常描述@warning         函数使用中需要注意的地方@remarks

zz 圣诞丨太阁所有的免费算法视频资料整理

首发于 太阁实验室 关注专栏 写文章 圣诞丨太阁所有的免费算法视频资料整理 Ray Cao· 12 小时前 感谢大家一年以来对太阁实验室的支持,我们特地整理了在过去一年中我们所有的原创算法类视频,均为免费观看,方便大家学习. 先放一个ACM大神讲解的算法题视频(国外传优酷真的是太不容易了……). ACM大神精讲北美最新面试题—在线播放—优酷网,视频高清在线观看http://v.youku.com/v_show/id_XMTg2ODk0MzIwMA==.html 其余视频: [公开课]ACM大神精