JSON 作為輕量級數據交換格式,已成為 Web API、AJAX 交互的標準。.NET Framework 3.5+ 內置 DataContractJsonSerializer 提供強大的序列化能力。本文系統講解其用法、日期時間處理、集合/字典序列化技巧,並提供可直接落地的輔助類代碼。
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
public static class JsonHelper
{
/// 序列化對象為 JSON 字符串
public static string Serialize<T>(T obj)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
/// 反序列化 JSON 字符串為對象
public static T Deserialize<T>(string json)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return (T)serializer.ReadObject(ms);
}
}
}
[DataContract]
public class Person
{
[DataMember] public string Name { get; set; }
[DataMember] public int Age { get; set; }
}
// 序列化
var p = new Person { Name = "張三", Age = 28 };
string json = JsonHelper.Serialize(p);
// 輸出: {"Age":28,"Name":"張三"}
// 反序列化
string jsonStr = "{\"Age\":28,\"Name\":\"張三\"}";
Person p2 = JsonHelper.Deserialize<Person>(jsonStr);
注意:必須標記 [DataContract] 與 [DataMember],否則屬性不會被序列化。
DataContractJsonSerializer 將 DateTime 序列化為 \"\\/Date(1294499956278+0800)\\/\"" 格式,前端難以直接使用。提供兩種解決方案:
public static class JsonHelper
{
private static readonly Regex DateRegex = new Regex(@\"\\/Date\((\d+)([+-]\d{4})?\)\\/\");
public static string Serialize<T>(T obj)
{
string json = /* 原始序列化 */;
return DateRegex.Replace(json, m => {
long ticks = long.Parse(m.Groups[1].Value);
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ticks);
return dt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
});
}
public static T Deserialize<T>(string json)
{
// 將 "yyyy-MM-dd HH:mm:ss" 轉回 JSON Date 格式供反序列化器識別
json = Regex.Replace(json, @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", m => {
DateTime dt = DateTime.Parse(m.Value).ToUniversalTime();
long ticks = (long)(dt - new DateTime(1970, 1, 1)).TotalMilliseconds;
return $\"\\/Date({ticks}+0800)\\/\";
});
return /* 反序列化 */;
}
}
function parseJsonDate(jsonDate) {
// "\/Date(1294499956278+0800)\/"
var ticks = parseInt(jsonDate.replace(/\D/g, ''), 10);
var date = new Date(ticks);
return date.getFullYear() + '-' +
('0' + (date.getMonth()+1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) + ' ' +
('0' + date.getHours()).slice(-2) + ':' +
('0' + date.getMinutes()).slice(-2) + ':' +
('0' + date.getSeconds()).slice(-2);
}
// List<T> 序列化為 JSON 數組
List<Person> list = new List<Person> {
new Person { Name = "張三", Age = 28 },
new Person { Name = "李四", Age = 25 }
};
string json = JsonHelper.Serialize(list);
// 結果: [{"Age":28,"Name":"張三"},{"Age":25,"Name":"李四"}]
// Dictionary 序列化:鍵值對轉為 {Key,Value} 對象數組
Dictionary<string, string> dic = new Dictionary<string, string> {
{ "Name", "張三" }, { "Age", "28" }
};
string json2 = JsonHelper.Serialize(dic);
// 結果: [{"Key":"Name","Value":"張三"},{"Key":"Age","Value":"28"}]
提示:若需標準鍵值對格式 {\"Name\":\"張三\",\"Age\":\"28\"},可先轉為匿名對象或使用 JavaScriptSerializer/Json.NET。
| 序列化器 | 命名空間 | 優點 | 缺點 |
|---|---|---|---|
| DataContractJsonSerializer | System.Runtime.Serialization.Json | 內置、支持 DataContract、流式處理 | 日期格式特殊、不支持匿名類型 |
| JavaScriptSerializer | System.Web.Script.Serialization | 簡單、支持匿名類型、日期友好 | 已過時、性能一般、無流式 API |
| Newtonsoft.Json (Json.NET) | Newtonsoft.Json | 功能最全、性能最好、生態最豐富 | 需額外引用 NuGet 包 |
DataContractJsonSerializer 是 .NET 內置的正規軍,適合對依賴控制嚴格、不願引入第三方庫的項目。掌握日期時間正則轉換與集合序列化規則,即可應對 90% 業務場景。新項目建議直接使用 Json.NET,獲得更佳開發體驗與性能。