Json.Net系列教程 3.Json.Net序列化和反序列化设置
首先補充一點,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我舉例說明DataTable的序列化和反序列化.
創(chuàng)建一個DataTable對象,如下:
序列化:
string json = JsonConvert.SerializeObject(dt);Console.WriteLine(json);結(jié)果:
利用上面得到的序列化字符串反序列化:
DataTable dt1 = JsonConvert.DeserializeObject<DataTable>(json);for (int i = 0; i < dt1.Rows.Count; i++){DataRow dr = dt1.Rows[i];Console.WriteLine("{0}\t{1}\t{2}\t", dr[0], dr[1], dr[2]);}結(jié)果:
本節(jié)內(nèi)容1.空值的處理
2.默認值的處理
3.忽略某些屬性
4.支持非公共成員
5.日期處理
6.FAQ
預(yù)備知識:
要想實現(xiàn)對Json.Net序列化和反序列化的控制,就要用到類JsonSerializerSettings,用法很簡單實例化一個對象,并把它賦值給JsonConvert的參數(shù)即可.
開始之前,我還是先創(chuàng)建一員工類:
public class Staff{public string Name { get; set; }public int Age { get; set; }public string Gender { get; set; }public string DepartmentName { get; set; }public Staff Leader { get; set; }} 一.空值的處理這里的空值指的是引用類型為NULL時,Json.Net如何處理.通過設(shè)置jSetting.NullValueHandling的值來確定,該值為枚舉類型.
| NullValueHandling.Ignore | 忽略為NULL的值 |
| NullValueHandling.Include | 默認值,包括為NULL的值 |
?
?
?
?
實例:
Staff jack = new Staff { Name = "Jack", Age = 31, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };var jSetting = new JsonSerializerSettings();jSetting.NullValueHandling = NullValueHandling.Ignore;string json = JsonConvert.SerializeObject(jack,jSetting);Console.WriteLine(json);結(jié)果:
2.默認值的處理?一般是對于值類型的處理,通過設(shè)置jSetting.DefaultValueHandling的值來確定,該值為枚舉類型.
| DefaultValueHandling.Ignore | 序列化和反序列化時,忽略默認值 |
| DefaultValueHandling.Include | 序列化和反序列化時,包含默認值 |
?
?
?
?
給成員設(shè)置默任值,用到"DefaultValue(value)"特性,當(dāng)然別忘了引入命名空間"System.ComponentModel",假設(shè)員工的年齡默認值為30
[DefaultValue(30)]public int Age { get; set; }序列化時我想忽略為默認值的成員
Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };var jSetting = new JsonSerializerSettings();jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;string json = JsonConvert.SerializeObject(jack,jSetting);Console.WriteLine(json);結(jié)果:
3.忽略某些屬性首先介紹Json.Net序列化的模式:OptOut 和 OptIn.
| OptOut | 默認值,類中所有公有成員會被序列化,如果不想被序列化,可以用特性JsonIgnore |
| OptIn | 默認情況下,所有的成員不會被序列化,類中的成員只有標(biāo)有特性JsonProperty的才會被序列化,當(dāng)類的成員很多,但客戶端僅僅需要一部分數(shù)據(jù)時,很有用 |
?
?
假如客戶僅僅需要員工的姓名,此時
[JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]public class Staff{[JsonProperty]public string Name { get; set; }public int Age { get; set; }public string Gender { get; set; }public string DepartmentName { get; set; }public Staff Leader { get; set; }}序列化:
Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };string json = JsonConvert.SerializeObject(jack);結(jié)果:
如果客戶不想要員工的領(lǐng)導(dǎo)信息
public class Staff{public string Name { get; set; }public int Age { get; set; }public string Gender { get; set; }public string DepartmentName { get; set; }[JsonIgnore]public Staff Leader { get; set; }}序列化:
Staff tom = new Staff { Name = "Tome", Age = 42, Gender = "Male", DepartmentName = "Personnel Department"};Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = tom };string json = JsonConvert.SerializeObject(jack);Console.WriteLine(json);結(jié)果:
4.支持非公共成員Json.Net序列化對象時,默認情況下僅僅序列化公有成員,如果想要非公有成員也被序列化,就要在該成員上加特性"JsonProperty"
5.日期處理JsonConverters會在序列化和反序列化時被用到。JsonConverters允許手動對Json的控制。當(dāng)Json的結(jié)構(gòu)很復(fù)雜和你想改變一個類型怎么樣被序列化時,這是非常有用的。當(dāng)一個JsonConverters被添加到JsonSerializer時,它會檢查每一要被序列化和反序列化的值,并返回CanConvert,如果為True,則JsonConverter讀和寫這個值;需要注意的是,雖然JsonConverter能夠使你可以完全的控制Json的值,但是很多的Json.Net序列化的特性被限制,像是類型名稱和引用處理。所有的JsonConvert都在命名空間 "Newtonsoft.Json.Converters"下
5.1IsoDateTimeConverter?和 JavaScriptDateTimeConverter這是Json.Net中自帶的兩個處理日期的類,默認是IsoDateTimeConverter?,它的格式是"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK".另一個是JavaScriptTimeConverter,它的格式是 "new Date(ticks)",其實返回的是一個JavaScript的Date對象.
有兩種方式來應(yīng)用JsonConverter,改變Json序列化和反序列化的行為.
假設(shè)我們?yōu)閱T工添加兩個日期類型的成員,出生日期和入職日期
我們的客戶要求日期類型的成員返回javascript的日期對象
Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male",DepartmentName = "Personnel Department", BirthDate = new DateTime(1982,2,12), EmploymentDate = new DateTime(2010,12,12) };string json = JsonConvert.SerializeObject(jack,new JavaScriptDateTimeConverter());Console.WriteLine(json);結(jié)果:
?
5.1.2如果想要不同的日期類型成員序列化后,以不同的形式顯示.現(xiàn)在我們的客戶要求出生日期以"ISO"標(biāo)準(zhǔn)日期格式返回,入職日期以Javascript的Date對象格式返回,修改我們的員工類
是的,通過特性"JsonConverter"來實現(xiàn)差異化的
序列化:
結(jié)果:
5.2自定義日期格式客戶現(xiàn)在提出要求,希望得到的日期格式是符合中國人習(xí)慣的格式.要求返回的格式是"2012年4月20日".挑戰(zhàn)來了,沒有挑戰(zhàn)就沒有進步,我喜歡挑戰(zhàn).光說是沒有用的!先分析一下怎么解決這個問題.我考慮了兩種思路.
思路一:
研究了一下上面兩個日期處理類,發(fā)現(xiàn)他們都是繼承了基類"DateTimeConverterBase",所以我們可以參考"IsoDatetimeConverter"的實現(xiàn)方式,自己新建一個處理日期格式的轉(zhuǎn)換器類.這種方式的缺點是可能要花大量的時間去研究,比較費時費力.優(yōu)點就是可以對日期格式隨心所欲的控制.
思路二:
我又研究了一下"IsoDatetimeConverter",發(fā)現(xiàn)它的日期格式其實是由于內(nèi)部DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"導(dǎo)致,而它也提供了修改日期樣式的屬性"DateTimeFormat",只要我們按照這種格式來寫就OK了.
?結(jié)果:
6.FAQ 1.如何自定義序列化的字段名稱? 默認情況下,Json.Net序列化后結(jié)果中的字段名稱和類中屬性的名稱一致.如果想自定義序列化后的字段名稱,可以使用JsonProperty.例如: public class Person{public int Id { get; set; }public string Name { get; set; }}默認序列化的結(jié)果為:?{"Id":1,"Name":"楊過"},如果不想用默認的字段名稱,可以使用如下方式:
public class Person {[JsonProperty(PropertyName = "PersonId")]public int Id { get; set; }[JsonProperty(PropertyName = "PersonName")]public string Name { get; set; } }這樣序列化的結(jié)果為:{"PersonId":1,"PersonName":"楊過"}
轉(zhuǎn)載于:https://www.cnblogs.com/usharei/archive/2012/04/20/2458858.html
總結(jié)
以上是生活随笔為你收集整理的Json.Net系列教程 3.Json.Net序列化和反序列化设置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 1964 Pipes
- 下一篇: (装载)C#中AppDomain.Cur