在無法使用JSON.NET的類別,又需要有JSON的相關作業需求時,.NET Framework內建的System.Runtime.Serialization.Json.DataContractJsonSerializer類別,會是你最好的夥伴,但這篇文章不是要教你怎麼使用(初步的使用方法詳見此篇:.NET Framework官方的JSON類別簡單存取範例),而是在處理使用過程中,如何移除(貼心)出現在JSON中的__type屬性欄位?
先來看下列的範例程式碼:
class Program { static void Main(string[] args) { Student oStudent = new Student() { cName="小明", cPhone ="0911" }; System.Runtime.Serialization.Json.DataContractJsonSerializer oJson = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(System.Collections.Generic.List<Student>)); using (System.IO.MemoryStream oMS = new System.IO.MemoryStream()) { oJson.WriteObject(oMS, oStudent); Write(System.Text.Encoding.UTF8.GetString(oMS.ToArray())); } } } public class Student { public string cName { get; set; } public string cPhone { get; set; } }
從上面的例子可以得知,理論上是要使用typeof(Student),而程式碼中卻去引用一個公用的泛型類別將Student類別集合化,導致於.NET的DataContractJsonSerializer類別無法識別這是啥合約的匿名物件,因此索性在JSON裡面跟你一次講個明白(這是啥米物件名稱)。所以如此一來,最後輸出的JSON會多出一個__type屬性欄位,輸出如下方所示:
{ "__type":"Student:#ConsoleApp1", << We wanna remove it! "cName":"小明", "cPhone":"0911" }
※P.S 這是一個不是很好的範例,但是沒辦法,有時候我們真的會有這方面的需求。
如果你把問題拋到StackOverflow,可能會得到一堆答案,叫你正規化類別並且好好的編寫合約。但是,有時候就是一個簡單的JSON輸出而已,沒有用匿名類別就很不錯了,還要編寫類別合約,有沒有搞錯?
其實,附掛參數加上EmitTypeInformation.Never屬性就可以了。
程式碼部分修改如下:
//建立序列化參數設定物件 var oRemoveTypeProperty = new System.Runtime.Serialization.Json.DataContractJsonSerializerSettings(); //設定轉換時不要顯示類別資訊 oRemoveTypeProperty.EmitTypeInformation = System.Runtime.Serialization.EmitTypeInformation.Never; //建立序列化物件(並且附掛參數) System.Runtime.Serialization.Json.DataContractJsonSerializer oJson = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(System.Collections.Generic.List<Student>), oRemoveTypeProperty);
經過上面兩行程式碼的修正後,輸出就變得很乾淨嘍!
{ "cName":"小明", "cPhone":"0911" }DataContractJsonSerializer "__type" ClassName JSON Property Remove Delete