ASP.NET 中JSON 的序列化和反序列化

作者: Asharp  來源: 博客園  發布時間: 2011-01-16 18:20  閱讀: 2366 次  推薦: 1   原文鏈接   [收藏]  

  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);
}

  運行結果:

image

  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);
 

  運行結果:

image

  在后臺替換字符串適用范圍比較窄,如果考慮到全球化的有多種語言還會更麻煩。

  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

1
0
 
標簽:ASP.NET JSON
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()