最近公司項目中用到了Json操作,從.NET后台讀取數據,通過Json轉化在傳給“Andiron”端呈現,於是通過幾天的學習,對它有了一點的理解!
1.Json的理解
Json其實就是一個序列化和反序列化的操作,而通過序列化操作之后的數據可以跨平台使用,這就促使了可以使用兩個平台,一個做后台,一個做前台,數據訪問層通過Json來傳遞!
2.可以序列化的標志
1 [Serializable] 2 public class MyPeople 3 { 4 public string Name { get; set; } 5
6 public string FatherName { get; set; } 7 }
從上面代碼可以看出要通過添加[Serializable]特性來標志這個對象是可以序列化的!
[NonSerialized] 特性,如果在你的屬性上面加上這個特性,就表示這個屬性將不會被序列化!
3.什么是序列化和可序列化
序列化首先從內存或其它文件中(MemorySteam或FileStream等)中把對象讀取出來並通過一定方式進行序列化,最后進行輸出!
反序列化首先會通過流操作(MemorySteam或FileStream等)讀取傳過來的值把它寫入內存或文件中,然后通過一定序列化方式轉化流對象 → 實體對象!
推薦文章 → [Serializable]在C#中的作用-NET 中的對象序列化
4.使用二進制(BinaryFormatter)進行序列化
4.1序列化
1 MyPeople myPeople = new MyPeople() { Name = "yangcaogui", FatherName = "caoxiaolong" }; 2 IFormatter binaryFormatter = new BinaryFormatter(); 3 using (Stream stream = new FileStream("one.txt", FileMode.Create, FileAccess.Write, FileShare.None)) //也可以使用MemoryStream內存流 4 { 5 binaryFormatter.Serialize(stream, myPeople); 6 stream.Close(); 7 }
4.2反序列化
1 IFormatter binaryFormatter = new BinaryFormatter(); 2 using (Stream streamOne = new FileStream("one.txt", FileMode.Open, FileAccess.Read, FileShare.None)) 3 { 4 MyPeople myPeopleOne = (MyPeople)binaryFormatter.Deserialize(streamOne); 5 Console.WriteLine(myPeopleOne.Name + "\t" + myPeopleOne.FatherName); 6 }
5.使用SoapFormatter進行序列化
這個跟二進制序列化不一樣的地方是 → 最后的數據是以XML的形式存在!
5.1序列化
5.2反序列化
基本代碼跟二進制反序列化一樣的,就不貼出來了!
6.使用XmlSerializer序列化
它使用的范圍比較廣,都可以對“DataContract”和“Serializable”標志的對象進行序列化和反序列化的操作!
它可以對一個“XML”的文件進行序列化!
6.1序列化
1 XmlSerializer xmlSerializer = new XmlSerializer(typeof(My)); 2 using (MemoryStream memoryStream = new MemoryStream()) 3 { 4 xmlSerializer.Serialize(memoryStream, my); 5 Console.WriteLine("\n\n------------------4→XmlSerializer------------------------------------\n\n"); 6 Console.WriteLine(Encoding.UTF8.GetString(memoryStream.ToArray())); 7 }
序列化格式如下:
6.2反序列化
1 XmlSerializer xmlSerializer = new XmlSerializer(typeof (My)); 2 using (MemoryStream memoryStreamOne = new MemoryStream(Encoding.UTF8.GetBytes(str), 0, str.Length)) // str 是我序列化之后的數據 3 { 4 My myOne = (My) xmlSerializer.Deserialize(memoryStreamOne); 5 Console.WriteLine("----------反序列化的結果------------------"); 6 Console.WriteLine(myOne.Name + "\t" + myOne.NameOne); 7 }
7.DataContractSerializer,DataContractJsonSerializer,NetDataContractSerializer
Note:DataContractSerializer 和DataContractJsonSerializer 需要.NET Frameword 3.5才能使用!
首先要序列化和反序列化的對象都要加上序列化的特性!
1 [DataContract] 2 public class My 3 { 4 [DataMember] 5 public string Name { get; set; } 6 7 [DataMember] 8 public string NameOne { get; set; } 9 10 public string NameTwo { get; set; } 11 }
Note:首先通過流操作把對象(可以是XML,內存中的對象,文本等形式)讀取出來,然后通過.NET Framework中的序列化算法把對象進行序列化!
下面就是這三種序列化的不同形式:
DataContractSerializer和NetDataContractSerializer序列化之后都是XML的格式,而DataContractJsonSerializer序列化之后就是常見的Json數據格式!
代碼如下:

Note:除了XmlSerializer序列化調用的方法是“Deserialize”,其它的序列化都是使用“ReadObject”進行反序列化操作!
8.一般的Json數據格式
9.理解序列化操作
下午在寫公共類庫的時候發現序列化其實就是流操作和序列化算法的結合,不管你使用哪一種流操作,最重要的還是你使用的是哪一種序列化算法,有“BinaryFormatter”,“SoapFormatter”,“XmlSerializer”,“DataContractSerialize”,“DataContractJsonSerializer”,“NetDataContractSerializer” 等,它們在序列化之后的格式有一定的差異!
10.關於Json序列化時間的問題
沒接觸過不知道問題所在,接觸過了才能猛然醒悟!
①如果把時間設置為“String”類型,如下:
②如果直接設置為“DataTime”,如下:
11.簡單的封裝Json操作類,解決時間問題
1 public static class JsonOperation<T>
2 { 3 private static readonly DataContractJsonSerializer DataContractJsonSerializer = new DataContractJsonSerializer(typeof(T)); 4
5 //序列化
6 public static string JsonSerializeOperation(T obj) 7 { 8 if (obj == null) 9 throw new Exception(); 10 string str = ""; 11 using (MemoryStream memoryStream = new MemoryStream()) 12 { 13 DataContractJsonSerializer.WriteObject(memoryStream, obj); 14 str = Encoding.UTF8.GetString(memoryStream.ToArray()); 15 } 16 return ConvertJsonTimeToDateTime(str); 17 } 18
19 //反序列化
20 public static T JsonDeserializeOperation(string str) 21 { 22 if (string.IsNullOrEmpty(str)) 23 throw new Exception(); 24 using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(str))) 25 { 26 return (T)DataContractJsonSerializer.ReadObject(memoryStream); 27 } 28 } 29
30 //二進制序列化
31 public static string BinarySerializeOperation(T obj) 32 { 33 string jsonString = ""; 34 if (obj == null) 35 throw new Exception(); 36 IFormatter formatter = new BinaryFormatter(); 37 using (MemoryStream memoryStream = new MemoryStream()) 38 { 39 formatter.Serialize(memoryStream, obj); 40 jsonString = Encoding.UTF8.GetString(memoryStream.ToArray()); 41 } 42 return jsonString; 43 } 44
45 //二進制反序列化
46 public static T BinaryDeserializeOperation(string str) 47 { 48 if (string.IsNullOrEmpty(str)) 49 throw new Exception(); 50 IFormatter formatter = new BinaryFormatter(); 51 using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(str))) 52 { 53 return (T)formatter.Deserialize(memoryStream); 54 } 55 } 56
57 /// <summary>
58 /// 把Json中的時間轉化為正規時間,現在是Json數據格式,需要轉化普通的時間格式 → yyyy-MM-dd HH:MM:ss 59 /// </summary>
60 /// <param name="jsonString">Json Time</param>
61 /// <returns></returns>
62 private static string ConvertJsonTimeToDateTime(string jsonString) 63 { 64 if (string.IsNullOrEmpty(jsonString)) 65 throw new Exception(); 66 const string matchDate = @"\\/Date\((\d+)\+\d+\)\\/"; 67 Regex regex = new Regex(matchDate); 68 Match match = regex.Match(jsonString); 69 foreach (var matchValue in match.Groups) 70 { 71 if (matchValue is Match) 72 { 73 Match matchOne = (Match)matchValue; 74 DateTime dateTime = JsonOperation<DateTime>.JsonDeserializeOperation(string.Format("\"{0}\"", matchOne.Value)); // This is very important.
75 jsonString = jsonString.Replace(matchOne.Value, dateTime.ToString("yyyy-MM-dd HH-MM-ss")); 76 } 77 } 78 return jsonString; 79 } 80 }