首先去官網下載最新的Newtonsoft.Json.dll(也可使用VS自帶的NuGet搜索Json.NET下載(下載下圖第二個))並引用至項目。json
using System; using Newtonsoft.Json; namespace Json_NET_Test { /// <summary>
/// 定義一個實體類 /// </summary>
public class Student { public string Name; public int Age; public string Class; } class Program { static void Main(string[] args) { //建立實體類對象
Student stu = new Student { Name = "老王", Age = 99, Class = "三班" }; //開始序列化
string jsonStr = JsonConvert.SerializeObject(stu, Formatting.Indented); Console.WriteLine(jsonStr); } } }
結果:ide
using System; using Newtonsoft.Json; namespace Json_NET_Test { /// <summary>
/// 定義一個實體類 /// </summary>
public class Student { public string Name; public int Age; public string Class; } class Program { static void Main(string[] args) { //Json字符串
string jsonStr = "{\"Name\": \"老王\",\"Age\": 99,\"Class\": \"三班\"}"; //開始反序列化
Student stu = JsonConvert.DeserializeObject<Student>(jsonStr); } } }
[JsonObject(MemberSerialization.OptIn)]用於在序列化與反序列化時忽略一個類裏全部的屬性,只有當在類內屬性上打特性標籤[JsonProperty]時才支持序列化與反序列化。因此[JsonObject(MemberSerialization.OptIn)]經常使用於與[JsonProperty]配合使用。網站
例:spa
[JsonObject(MemberSerialization.OptIn)] public class Person { public int Age { get; set; } [JsonProperty] public string Name { get; set; } public string Sex { get; set; } public bool IsMarry { get; set; } public DateTime Birthday { get; set; } }
默認實體類上默認打着[JsonObject(MemberSerialization.OptOut)]特性標籤(能夠省略不寫),若是要忽略某些屬性,要在屬性上打[JsonIgnore]。3d
例:code
[JsonObject(MemberSerialization.OptOut)] public class Person { public int Age { get; set; } public string Name { get; set; } public string Sex { get; set; } [JsonIgnore] public bool IsMarry { get; set; } public DateTime Birthday { get; set; } }
當某些條件下須要序列化A屬性和B屬性,某些狀況下須要忽略A屬性與B屬性,咱們該怎麼作?
答:使用JsonSerializerSettings設置某實體類對象要忽略序列化的屬性(配合if與else控制屬性的動態忽略)。orm
例:如下方式忽略p對象的Age屬性與IsMarry屬性:對象
JsonSerializerSettings jsetting=new JsonSerializerSettings(); jsetting.ContractResolver = new LimitPropsContractResolver(new string[] { "Age", "IsMarry" }); Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));
在屬性上打 [DefaultValue("xxx")]blog
3.空值處理繼承
Person p = new Person { room = null, Age = 10, Name = "張三丰", Sex = "男", IsMarry = false, Birthday = new DateTime(1991, 1, 2) }; JsonSerializerSettings jsetting=new JsonSerializerSettings(); jsetting.NullValueHandling = NullValueHandling.Ignore; Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));
ps:使用這種方式可能bool爲false的也沒法序列,最後的結果只包含Birthday、Sex、Name、Age。
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)] public Room room { get; set; }
由於默認只序列化public的成員,因此若是想序列化private成員,要在實體類的屬性上打[JsonProperty]標籤。
[JsonProperty] private int Height { get; set; }
5.自定義序列化名稱
在序列化與反序列化時能夠自定義序列化出字符串的屬性名稱,以下代碼能夠將實體類的Name屬性序列化爲CName屬性,而且能夠將Json中的CName反序列化爲當前實體類的Name屬性。(雙向)
[JsonProperty(PropertyName = "CName")] public string Name { get; set; }
6.日期處理
系統自帶的DateTime會格式化成iso日期標準,可是實際使用過程當中大多數使用的多是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss兩種格式的日期,解決辦法是能夠將DateTime類型改爲string類型本身格式化好,而後在序列化。
例:
[JsonProperty(PropertyName = "startTime")]//由於默認只序列化public屬性,因此要打上JsonProperty標籤而且聲明名稱 private string m_StartTime{get;set;} [JsonIgnore]//這個標籤用於在序列化與反序列化時忽略StartTime屬性 public DateTime StartTime { get{ return Convert.ToDateTime(m_StartTime); } set { DateTime time = value; m_StartTime = time.ToString("yyyy-MM-dd");//這裏寫本身想要的格式
} }
ps:代碼思路是不去序列化StartTime屬性,而去序列化string類型的m_StartTime屬性(m_StartTime至關於StartTime屬性的私有字段)。
Json.Net提供了IsoDateTimeConverter日期轉換這個類,能夠經過JsnConverter實現相應的日期轉換
[JsonConverter(typeof(IsoDateTimeConverter))] public DateTime Birthday { get; set; }
可是IsoDateTimeConverter日期格式(yyyy-MM-ddTHH:mm:ss)不是咱們想要的,咱們能夠繼承該類實現本身的日期
例:
public class ChinaDateTimeConverter : DateTimeConverterBase { private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" }; public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return dtConverter.ReadJson(reader, objectType, existingValue, serializer); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { dtConverter.WriteJson(writer, value, serializer); } }
使用方式:
[JsonConverter(typeof(ChinaDateTimeConverter))] public DateTime Birthday { get; set; }
7.以駝峯命名法序列化
有時咱們會碰到這種需求,好比咱們代碼裏實體類型的屬性名稱均是以大寫字母開頭,如Name、StartTime等,可是要求咱們序列出的Json字符串的屬性名稱要以小寫字母開頭,如name、startTime、endTime等。咱們可使用以下代碼解決
JsonSerializerSettings setting = new JsonSerializerSettings(); setting.ContracResolver = new CamelCasePropertyNamesContractResolver(); string jsonStr = JsonConvert.Serializeobject(p, Newtonsoft.json.Formatting.Indented, setting);
這樣子的話,在序列實體類對象p的屬性時,屬性名稱將由PersonName轉換爲personName。
8.枚舉的序列化
枚舉默認序列化爲枚舉的Int值,若是想要序列化爲枚舉string值,使用以下方式
9.將多個數據類型序列化爲1個Json對象(序列化匿名類)
有時咱們有這樣的需求,對方要求咱們傳輸過去的Json字符串要包含咱們多個實體類型的信息,笨方法就是從新構建一個符合要求的實體類型,可是咱們又更好的方法,咱們可使用匿名類,把Json須要的信息均放在匿名類中,咱們能夠對匿名類進行序列化。
例:
List<Model> list1 = new List<Model>(); List<Model2> list2 = new List<Model2>(); string name = "名字"; string address = "xx"; List<string> info = new List<string>() { name, address }; var json = new { information = info, jsonList1 = list1, jsonList2 = list2 };
咱們只須要對上面的匿名對象「json」序列化便可。
10.使用JsonConverter自定義屬性序列化規則(json格式轉換器)
public class DoubleToStringConverter : JsonConverter { //表示反序列化時不執行該轉換器
public override bool CanRead => false; //表示序列化時執行該轉換器
public override bool CanWrite => true; //判斷執行條件(當屬性的值爲double類型時才使用轉換器)
public override bool CanConvert(Type objectType) { return objectType == typeof(double); } //由於public override bool CanRead => false;,因此不用實現反序列化時的轉換方法
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } /// <summary>
/// 序列化時執行的轉換 /// </summary>
/// <param name="writer">能夠用來重寫值</param>
/// <param name="value">屬性的原值</param>
/// <param name="serializer">就是那個serializer對象</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { double v = (double)value; writer.WriteValue(v.ToString()); } }
使用方式:
[JsonConverter(typeof(DoubleToStringConverter))] public double Count{get;set;}
ps:這樣子,就能夠把本來序列化出的Json字符串 Count : 12.3 轉化爲 Count : "12.3"
ps:[JsonConverter(typeof(DoubleToStringConverter))]也能夠打在類上,表示全局設置
爲何要進行這樣的轉換呢?
由於枚舉類型在序列化時默認序列化爲枚舉的int類型,即以下代碼:
/// <summary> /// 自定義一個枚舉類型 /// </summary> public enum MyEnum { aaa = 1, bbb = 2, ccc = 3 } /// <summary> /// 實體類(類內有一個枚舉類型的屬性MyEnumProp) /// </summary> public class Person { public MyEnum MyEnumProp { get; set; } } class Program { static void Main(string[] args) { Person p = new Person() { MyEnumProp = MyEnum.ccc }; //Json字符串 string jsonStr = JsonConvert.SerializeObject(p); //開始反序列化 Console.WriteLine(jsonStr); Console.ReadLine(); } }
結果爲:
有時候會有這樣的需求,序列化出的屬性值均要爲字符串格式,即要將上圖結果的3改成"3"。這時候就須要自定義轉換了!
代碼以下:
public class EnumToIntStringConverter : JsonConverter { //反序列化時不執行
public override bool CanRead => false; //序列化時執行
public override bool CanWrite => true; //控制執行條件(當屬性的值爲枚舉類型時才使用轉換器)
public override bool CanConvert(Type objectType) { return objectType == typeof(Enum); } //由於public override bool CanRead => false;,因此不用實現反序列化時的轉換方法
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } /// <summary>
/// 序列化時執行的轉換 /// </summary>
/// <param name="writer">能夠用來重寫值</param>
/// <param name="value">屬性的原值</param>
/// <param name="serializer">就是那個serializer對象</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Enum e = (Enum)value; int v = Convert.ToInt32(e); writer.WriteValue(v.ToString()); } }
使用方法同上例。