JSON 是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式。在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中 JSON的序列化和反序列化,主要对JSON的简单介绍,ASP.NET如何序列化和反序列化的处理,在序列化和反序列化对日期时间、集合、字典的处理。
一、JSON简介
JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式。
JSON是“名值对”的集合。结构由大括号'{}',中括号'[]',逗号',',冒号':',双引号'“”'组成,包含的数据类型有Object,Number,Boolean,String,Array, NULL等。
JSON具有以下的形式:
对象(Object)是一个无序的“名值对”集合,一个对象以”{”开始,”}”结束。每个“名”后跟着一个”:”,多个“名值对”由逗号分隔。如:
var
user
=
{
"
name
"
:
"
张三
"
,
"
gender
"
:
"
男
"
,
"
birthday
"
:
"
1980-8-8
"
}
数组(Array)是值的有序集合,一个数组以“[”开始,以“]”结束,值之间使用“,”分隔。如:
var
userlist
=
[{
"
user
"
:{
"
name
"
:
"
张三
"
,
"
gender
"
:
"
男
"
,
"
birthday
"
:
"
1980-8-8
"
}},{
"
user
"
:{
"
name
"
:
"
李四
"
,
"
gender
"
:
"
男
"
,
"
birthday
"
:
"
1985-5-8
"
}}];
字符串(String)是由双引号包围的任意数量的Unicode字符的集合,使用反斜线转义。
二、对JSON数据进行序列化和反序列化
可以使用DataContractJsonSerializer类将类型实例序列化为JSON字符串,并将JSON字符串反序列化为类型实例。 DataContractJsonSerializer在System.Runtime.Serialization.Json命名空间下,.NET Framework 3.5包含在System.ServiceModel.Web.dll中,需要添加对其的引用;.NET Framework 4在System.Runtime.Serialization中。
利用DataContractJsonSerializer序列化和反序列化的代码:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Runtime.Serialization.Json;
using
System.IO;
using
System.Text;
///
<summary>
///
JSON序列化和反序列化辅助类
///
</summary>
public
class
JsonHelper
{
///
<summary>
///
JSON序列化
///
</summary>
public
static
string
JsonSerializer
<
T
>
(T t)
{
DataContractJsonSerializer ser
=
new
DataContractJsonSerializer(
typeof
(T));
MemoryStream ms
=
new
MemoryStream();
ser.WriteObject(ms, t);
string
jsonString
=
Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return
jsonString;
}
///
<summary>
///
JSON反序列化
///
</summary>
public
static
T JsonDeserialize
<
T
>
(
string
jsonString)
{
DataContractJsonSerializer ser
=
new
DataContractJsonSerializer(
typeof
(T));
MemoryStream ms
=
new
MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj
=
(T)ser.ReadObject(ms);
return
obj;
}
}
序列化Demo:
简单对象Person:
public
class
Person
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
}
序列化为JSON字符串:
protected
void
Page_Load(
object
sender, EventArgs e)
{
Person p
=
new
Person();
p.Name
=
"
张三
"
;
p.Age
=
28
;
string
jsonString
=
JsonHelper.JsonSerializer
<
Person
>
(p);
Response.Write(jsonString);
}
输出结果:
{
"
Age
"
:
28
,
"
Name
"
:
"
张三
"
}
反序列化Demo:
protected
void
Page_Load(
object
sender, EventArgs e)
{
string
jsonString
=
"
{\
"
Age\
"
:28,\
"
Name\
"
:\
"
张三\
"
}
"
;
Person p
=
JsonHelper.JsonDeserialize
<
Person
>
(jsonString);
}
运行结果:

ASP.NET中的JSON序列化和反序列化还可以使用JavaScriptSerializer,在 System.Web.Script.Serializatioin命名空间下,需引用System.Web.Extensions.dll.也可以使用 JSON.NET.
三、JSON序列化和反序列化日期时间的处理
JSON格式不直接支持日期和时间。DateTime值值显示为“/Date(700000+0500)/”形式的JSON字符串,其中第一个数字(在 提供的示例中为 700000)是 GMT 时区中自 1970 年 1 月 1 日午夜以来按正常时间(非夏令时)经过的毫秒数。该数字可以是负数,以表示之前的时间。示例中包括“+0500”的部分可选,它指示该时间属于Local 类型,即它在反序列化时应转换为本地时区。如果没有该部分,则会将时间反序列化为Utc。
修改Person类,添加LastLoginTime:
public
class
Person
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
public
DateTime LastLoginTime {
get
;
set
; }
}
Person p
=
new
Person();
p.Name
=
"
张三
"
;
p.Age
=
28
;
p.LastLoginTime
=
DateTime.Now;
string
jsonString
=
JsonHelper.JsonSerializer
<
Person
>
(p);
序列化结果:
{
"
Age
"
:
28
,
"
LastLoginTime
"
:
"
\/Date(1294499956278+0800)\/
"
,
"
Name
"
:
"
张三
"
}
1 、在后台使用正则表达式对其替换处理。修改JsonHelper:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Runtime.Serialization.Json;
using
System.IO;
using
System.Text;
using
System.Text.RegularExpressions;
///
<summary>
///
JSON序列化和反序列化辅助类
///
</summary>
public
class
JsonHelper
{
///
<summary>
///
JSON序列化
///
</summary>
public
static
string
JsonSerializer
<
T
>
(T t)
{
DataContractJsonSerializer ser
=
new
DataContractJsonSerializer(
typeof
(T));
MemoryStream ms
=
new
MemoryStream();
ser.WriteObject(ms, t);
string
jsonString
=
Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
//
替换Json的Date字符串
string
p
=
@"
\\/Date\((\d+)\+\d+\)\\/
"
;
MatchEvaluator matchEvaluator
=
new
MatchEvaluator(ConvertJsonDateToDateString);
Regex reg
=
new
Regex(p);
jsonString
=
reg.Replace(jsonString, matchEvaluator);
return
jsonString;
}
///
<summary>
///
JSON反序列化
///
</summary>
public
static
T JsonDeserialize
<
T
>
(
string
jsonString)
{
//
将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式
string
p
=
@"
\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}
"
;
MatchEvaluator matchEvaluator
=
new
MatchEvaluator(ConvertDateStringToJsonDate);
Regex reg
=
new
Regex(p);
jsonString
=
reg.Replace(jsonString, matchEvaluator);
DataContractJsonSerializer ser
=
new
DataContractJsonSerializer(
typeof
(T));
MemoryStream ms
=
new
MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj
=
(T)ser.ReadObject(ms);
return
obj;
}
///
<summary>
///
将Json序列化的时间由/Date(1294499956278+0800)转为字符串
///
</summary>
private
static
string
ConvertJsonDateToDateString(Match m)
{
string
result
=
string
.Empty;
DateTime dt
=
new
DateTime(
1970
,
1
,
1
);
dt
=
dt.AddMilliseconds(
long
.Parse(m.Groups[
1
].Value));
dt
=
dt.ToLocalTime();
result
=
dt.ToString(
"
yyyy-MM-dd HH:mm:ss
"
);
return
result;
}
///
<summary>
///
将时间字符串转为Json时间
///
</summary>
private
static
string
ConvertDateStringToJsonDate(Match m)
{
string
result
=
string
.Empty;
DateTime dt
=
DateTime.Parse(m.Groups[
0
].Value);
dt
=
dt.ToUniversalTime();
TimeSpan ts
=
dt
-
DateTime.Parse(
"
1970-01-01
"
);
result
=
string
.Format(
"
\\/Date({0}+0800)\\/
"
,ts.TotalMilliseconds);
return
result;
}
}
序列化Demo:
Person p
=
new
Person();
p.Name
=
"
张三
"
;
p.Age
=
28
;
p.LastLoginTime
=
DateTime.Now;
string
jsonString
=
JsonHelper.JsonSerializer
<
Person
>
(p);
运行行结果:
{
"
Age
"
:
28
,
"
LastLoginTime
"
:
"
2011-01-09 01:00:56
"
,
"
Name
"
:
"
张三
"
}
反序列化Demo:
string
json
=
"
{\
"
Age\
"
:28,\
"
LastLoginTime\
"
:\
"
2011
-
01
-
09
00
:
30
:
00
\
"
,\
"
Name\
"
:\
"
张三\
"
}
"
;
p
=
JsonHelper.JsonDeserialize
<
Person
>
(json);
运行结果:

在后台替换字符串适用范围比较窄,如果考虑到全球化的有多种语言还会更麻烦。
2、利用JavaScript处理
function ChangeDateFormat(jsondate) {
jsondate
=
jsondate.replace(
"
/Date(
"
,
""
).replace(
"
)/
"
,
""
);
if
(jsondate.indexOf(
"
+
"
)
>
0
) {
jsondate
=
jsondate.substring(
0
, jsondate.indexOf(
"
+
"
));
}
else
if
(jsondate.indexOf(
"
-
"
)
>
0
) {
jsondate
=
jsondate.substring(
0
, jsondate.indexOf(
"
-
"
));
}
var date
=
new
Date(parseInt(jsondate,
10
));
var month
=
date.getMonth()
+
1
<
10
?
"
0
"
+
(date.getMonth()
+
1
) : date.getMonth()
+
1
;
var currentDate
=
date.getDate()
<
10
?
"
0
"
+
date.getDate() : date.getDate();
return
date.getFullYear()
+
"
-
"
+
month
+
"
-
"
+
currentDate;
}
简单Demo :
ChangeDateFormat(
"
\/Date(1294499956278+0800)\/
"
);
结果:2011-1-8
四、JSON序列化和反序列化集合、字典、数组的处理
在JSON数据中,所有的集合、字典和数组都表示为数组。
List<T>序列化:
List
<
Person
>
list
=
new
List
<
Person
>
()
{
new
Person(){ Name
=
"
张三
"
, Age
=
28
},
new
Person(){ Name
=
"
李四
"
, Age
=
25
}
};
string
jsonString
=
JsonHelper.JsonSerializer
<
List
<
Person
>>
(list);
序列化结果:
"
[{\
"
Age\
"
:28,\
"
Name\
"
:\
"
张三\
"
},{\
"
Age\
"
:25,\
"
Name\
"
:\
"
李四\
"
}]
"
字典不能直接用于JSON,Dictionary字典转化为JSON并不是跟原来的字典格式一致,而是形式以Dictionary的Key作为名称”Key“的值,以Dictionary的Value作为名称为”Value“的值 。如:
Dictionary
<
string
,
string
>
dic
=
new
Dictionary
<
string
,
string
>
();
dic.Add(
"
Name
"
,
"
张三
"
);
dic.Add(
"
Age
"
,
"
28
"
);
string
jsonString
=
JsonHelper.JsonSerializer
<
Dictionary
<
string
,
string
>>
(dic);
序列化结果:
"
[{\
"
Key\
"
:\
"
Name\
"
,\
"
Value\
"
:\
"
张三\
"
},{\
"
Key\
"
:\
"
Age\
"
,\
"
Value\
"
:\
"
28
\
"
}]
"
JSON官网:http://www.json.org/json-zh.html
独立JSON序列化:http://msdn.microsoft.com/zh-cn/library/bb412170.aspx
如何对JSON序列化和反序列化:http://msdn.microsoft.com/zh-cn/library/bb412179.aspx