[.net]使用JavaScriptSerializer序列化、反序列化處理DateTime問題

[.net]使用JavaScriptSerializer序列化、反序列化處理DateTime問題

前言

今天透過JavaScriptSerializer處理物件的序列化及反序列化時,發現日期屬性的時間會有差異。

說明

先建立測試的Class、序列化及反序化Method


//測試的Class
public class c1
{
    public string id { get; set; } 
    public DateTime dv {get; set;} 
}

//序列化及反序列化Method
private static readonly JavaScriptSerializer _jsonConverter = new JavaScriptSerializer();
public static T JSON2Object<T>(string serializeString)
{
    return (T)_jsonConverter.Deserialize(serializeString, typeof(T));
}
public static string Object2JSON(Object Obj)
{
    string result = _jsonConverter.Serialize(Obj); ;
    return result;
}

執行測試程式


//建立c1 Class,並設定初始值
c1 orgC1 = new c1 { id = "c1", dv =  DateTime.Now  };
//序列化
string c1JSON = Object2JSON(orgC1);
//反序列化
c1 deC1 = JSON2Object<c1>(c1JSON);
//顯示序列化前與序列化後的屬性值
MessageBox.Show(string.Format("orgC1.dv:{0} \n deC1.dv:{1}", orgC1.dv.ToString(), deC1.dv.ToString()));

從下圖可發現,c1JSON.dv的Kind為Local,而deC1.dv的為Utc,所以2個日期有差距。

image

image

所以要把序列化後的日期屬性轉成Local來顯示才對(deC1.dv.ToLocalTime()),如下,


MessageBox.Show(string.Format("orgC1.dv:{0} \n deC1.dv:{1}", orgC1.dv.ToString(), deC1.dv.ToLocalTime().ToString()));

image

或著是在序列化前,先轉成UTC(DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc)),也是可以的,如下,


//建立c1 Class,並設定初始值,dv日期屬性設定為Utc
c1 orgC1 = new c1 { id = "c1", dv = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc) };
string c1JSON = Object2JSON(orgC1);
c1 deC1 = JSON2Object<c1>(c1JSON);
MessageBox.Show(string.Format("orgC1.dv:{0} \n deC1.dv:{1}", orgC1.dv.ToString(), deC1.dv.ToString()));

image

結論

使用JavasacriptSerializer在反序列化時,遇到日期屬性會將它反序化回UTC,所以在使用上要注意一下差異。

參考資料

Serializing DateTime values using JavaScriptSerializer class.

[C#] 使用JavasacriptSerializer序列化Entity為Json

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^