Newtonsoft.Json 的序列化與反序列化

首先補充一點,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我舉例說明DataTable的序列化和反序列化.
建立一個DataTable對象,以下:javascript

 DataTable dt = new DataTable();
            DataColumn dcName = new DataColumn("Name");
            DataColumn dcAge = new DataColumn("Age");
            DataColumn dcCity = new DataColumn("City");

            dt.Columns.Add(dcName);
            dt.Columns.Add(dcAge);
            dt.Columns.Add(dcCity);
            for (int i = 0; i < 10; i++)
            {
                DataRow dr = dt.NewRow();
                dr[0] = "Name" + i;
                dr[1] = "Age" + i;
                dr[2] = "City" + i;
                dt.Rows.Add(dr);
            }

序列化:html

            string json = JsonConvert.SerializeObject(dt);
            Console.WriteLine(json);

結果:java

利用上面獲得的序列化字符串反序列化:json

          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]);
            }

結果:spa

本節內容

預備知識:

要想實現對Json.Net序列化和反序列化的控制,就要用到類JsonSerializerSettings,用法很簡單實例化一個對象,並把它賦值給JsonConvert的參數便可.

            var jSetting = new JsonSerializerSettings();
            string json = JsonConvert.SerializeObject(obj,jSetting);

開始以前,我仍是先建立一員工類:

    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如何處理.經過設置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);

結果:

2.默認值的處理

 通常是對於值類型的處理,經過設置jSetting.DefaultValueHandling的值來肯定,該值爲枚舉類型.

DefaultValueHandling.Ignore
序列化和反序列化時,忽略默認值
DefaultValueHandling.Include
序列化和反序列化時,包含默認值

 

 

 

 

給成員設置默任值,用到"DefaultValue(value)"特性,固然別忘了引入命名空間"System.ComponentModel",假設員工的年齡默認值爲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);

結果:

3.忽略某些屬性

首先介紹Json.Net序列化的模式:OptOut 和 OptIn.

OptOut 默認值,類中全部公有成員會被序列化,若是不想被序列化,能夠用特性JsonIgnore
OptIn 默認狀況下,全部的成員不會被序列化,類中的成員只有標有特性JsonProperty的纔會被序列化,當類的成員不少,但客戶端僅僅須要一部分數據時,頗有用

 

 

假如客戶僅僅須要員工的姓名,此時

[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);

結果:

若是客戶不想要員工的領導信息

 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);

結果:

4.支持非公共成員

Json.Net序列化對象時,默認狀況下僅僅序列化公有成員,若是想要非公有成員也被序列化,就要在該成員上加特性"JsonProperty"

5.日期處理

  JsonConverters會在序列化和反序列化時被用到。JsonConverters容許手動對Json的控制。當Json的結構很複雜和你想改變一個類型怎麼樣被序列化時,這是很是有用的。當一個JsonConverters被添加到JsonSerializer時,它會檢查每一要被序列化和反序列化的值,並返回CanConvert,若是爲True,則JsonConverter讀和寫這個值;須要注意的是,雖然JsonConverter可以使你能夠徹底的控制Json的值,可是不少的Json.Net序列化的特性被限制,像是類型名稱和引用處理。全部的JsonConvert都在命名空間 "Newtonsoft.Json.Converters"

5.1 IsoDateTimeConverter  JavaScriptDateTimeConverter

這是Json.Net中自帶的兩個處理日期的類,默認是IsoDateTimeConverter ,它的格式是"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK".另外一個是JavaScriptTimeConverter,它的格式是 "new Date(ticks)",其實返回的是一個JavaScript的Date對象.
有兩種方式來應用JsonConverter,改變Json序列化和反序列化的行爲.

5.1.1若是你要序列化的日期格式是統一的,能夠考慮以下方式

假設咱們爲員工添加兩個日期類型的成員,出生日期和入職日期

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; }
        public DateTime BirthDate { get; set; }
        public DateTime EmploymentDate { get; set; }
    }

咱們的客戶要求日期類型的成員返回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);

結果:

 

5.1.2若是想要不一樣的日期類型成員序列化後,以不一樣的形式顯示.

如今咱們的客戶要求出生日期以"ISO"標準日期格式返回,入職日期以Javascript的Date對象格式返回,修改咱們的員工類

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; }
        [JsonConverter(typeof(IsoDateTimeConverter))]
        public DateTime BirthDate { get; set; }
        [JsonConverter(typeof(JavaScriptDateTimeConverter))]
        public DateTime EmploymentDate { get; set; }
    }

是的,經過特性"JsonConverter"來實現差別化的
序列化:

 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);
            Console.WriteLine(json);

結果:

5.2自定義日期格式

客戶如今提出要求,但願獲得的日期格式是符合中國人習慣的格式.要求返回的格式是"2012年4月20日".挑戰來了,沒有挑戰就沒有進步,我喜歡挑戰.光說是沒有用的!先分析一下怎麼解決這個問題.我考慮了兩種思路.
  思路一:
研究了一下上面兩個日期處理類,發現他們都是繼承了基類"DateTimeConverterBase",因此咱們能夠參考"IsoDatetimeConverter"的實現方式,本身新建一個處理日期格式的轉換器類.這種方式的缺點是可能要花大量的時間去研究,比較費時費力.優勢就是能夠對日期格式爲所欲爲的控制.
  思路二:
我又研究了一下"IsoDatetimeConverter",發現它的日期格式實際上是因爲內部DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"致使,而它也提供了修改日期樣式的屬性"DateTimeFormat",只要咱們按照這種格式來寫就OK了.

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) };
            IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy'年'MM'月'dd'日'" };
            string json = JsonConvert.SerializeObject(jack,dtConverter);
            Console.WriteLine(json);

 結果:

相關文章
相關標籤/搜索