在我的項目代碼中,我習慣於把一些對象進行序列化,然後存入資料庫,出於節省空間的考慮,我一般使用.net 4.0中帶的DataContractJsonSerializer類來實現,一般我我會寫兩個方法(Serialize方法和Deserialize方法)放到我的Utility項目中。
Serialize和Deserialize方法分別如下:
/// <summary>
/// Serialize T to string
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public static string Serialize<T>(T item)
{
if (item == null) return string.Empty;
var serializer = new DataContractJsonSerializer(item.GetType());
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, item);
var sb = new StringBuilder();
sb.Append(Encoding.UTF8.GetString(ms.ToArray()));
return sb.ToString();
}
}
/// <summary>
/// Deserialize string back to T
/// </summary>
/// <param name="jsonString"></param>
/// <returns></returns>
public static T Deserialize<T>(string jsonString)
{
if (string.IsNullOrEmpty(jsonString)) return default(T);
var ser = new DataContractJsonSerializer(typeof(T));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
{
T jsonObject = (T)ser.ReadObject(ms);
return jsonObject;
}
}
但是在使用過程中碰到過兩種問題,第一個是DateTime.MinValue不能序列化的問題。錯誤提示資訊如下:
“在轉換為 UTC 時,大於 DateTime.MaxValue 或小於 DateTime.MinValue 的 DateTime 值無法序列化為 JSON。”
根據錯誤資訊的意思來看,其意思是在將DateTime.MinValue轉換為Utc時間後,再序列化出現錯誤,而且轉換為Utc時間後,Utc時間出現了大於DateTime.MaxValue或小於DateTime.MinValue的情況,真是百思不得其解。難道在DataContract將LocalTime的時間轉換為UtcTime時不時使用TimeZoneInfo.ConvertTimeToUtc的嗎?
對於這個問題沒辦法,我只好使用SqlDateTime.MinValue來代替DateTime.MinValue,而且每次都要加一層轉換,也比較麻煩。
第二個問題是,裝箱後資料類型的丟失問題,例如把一個Guid類型的資料給一個object的屬性或成員,而序列化後,再還原序列化回來的對象的值(object)則不再是一個Guid的值了,而變成了一個string類型的值了。這個問題是我在把一些介面操作資料儲存到本地文字檔然後載入這些檔案序列化的時候發現的。這個問題對於DataContractJsonSerializer來說似乎是個很難解決的問題。所以在使用DataContractJsonSerializer的時候應儘可能的避免使用object類型的設計。原範例程式碼如下:
Data2 d2 = new Data2 { Uid = Guid.NewGuid (), Value = Guid.NewGuid() };Console.WriteLine("d2.Value is Guid: {0}", d2.Value is Guid);string d2String = Serialize<Data2>(d2);Console.WriteLine("----------------------------------------------------");Console.WriteLine(d2String);Console.WriteLine("----------------------------------------------------");Data2 d22 = Deserialize<Data2>(d2String);Console.WriteLine("d22.Value is Guid: {0}", d22.Value is Guid);