歡迎光臨
每天分享高質量文章

在C#中使用Json.Net進行序列化和反序列化及定製化

  序列化(Serialize)是將物件轉換成位元組流,並將其用於儲存或傳輸的過程,主要用途是儲存物件的狀態,以便在需要時重新建立該物件;反序列化(Deserialize)則是將上面的位元組流轉換為相應物件的過程;在.Net陣營中,Json.Net是由官方推薦的高效能開源序列化/反序列化工具,其官方網站:https://www.newtonsoft.com/json;

  一、將物件序列化為Json格式字串

  首先是正常的序列化操作,對於給定的類:

private class MyClass
{
    public int MyNum;
    public string MyStr;
}

  將該類的實體序列化為Json格式字串,首先取用名稱空間Newtonsoft.Json:

MyClass myClass = new MyClass { MyNum = 10, MyStr = "Hello World" };
Console.WriteLine(JsonConvert.SerializeObject(myClass));

  其列印結果:

{"MyNum":10,"MyStr":"Hello World"}

  在列印到本地Log檔案以供自己檢視使用時,可以選擇轉換為帶有縮排的Json格式字串:

Console.WriteLine(JsonConvert.SerializeObject(myClass, Formatting.Indented));

  此時列印結果為:

{
  "MyNum": 10,
  "MyStr": "Hello World"
}

  二、將Json格式字串反序列化為物件

  對於給定的字串:

string jsonStr = @"{""MyNum"": 10,""MyStr"": ""Hello World""}";

  將其反序列化為MyClass型別的物件:

MyClass myClass = JsonConvert.DeserializeObject(jsonStr);
Console.WriteLine(myClass.MyStr);  //Hello World

  三、使用JObject動態序列化/反序列化

  以上例子都是使用強型別進行序列化和反序列操作,但有時也會用到不指定型別而直接操作Json格式資料的情況,此時就需要用位於名稱空間ewtonsoft.Json.Linq中的JObject型別的物件:

string jsonStr = @"{""MyNum"": 10,""MyStr"": ""Hello World""}";
JObject jObject = JObject.Parse(jsonStr);
Console.WriteLine(jObject.ToString(Formatting.None));  //{"MyNum":10,"MyStr":"Hello World"}
//列印一條屬性的值
Console.WriteLine(jObject["MyStr"].Value<string>());  //Hello World
//新增一條屬性
jObject.Add("MyStr2", "HaHa");
//列印當前Json字串
Console.WriteLine(jObject.ToString(Formatting.None));  //{"MyNum":10,"MyStr":"Hello World","MyStr2":"HaHa"}

 四、定製化序列化/反序列過程

  1.在C#中,定製化的配置通常使用特性來完成,這裡也不例外,例如簡單的,在序列化/反序列時忽略某個欄位/屬性:

private class MyClass
{
    [JsonIgnore]
    public int MyNum;
    public string MyStr;
}

  此時,無論序列化還是反序化時,欄位MyNum都不再參與這些過程;

  2.自定義某個欄位/屬性的序列化/反序列化規則:

  當接收到的Json格式字串與本地已有型別不統一時,需要進行自定義的反序列化過程,反之亦然,例如Json字串中以字串”TRUE”表示布林型別true(不自定義,這個過程依然走的通,只是以此舉例),以字串”FALSE”表示布林型別false時,需要自定義如下:

/// 
/// 自定義布林型別資料轉換規則
///

public class MyBoolConverter : JsonConverter
{
private const string TrueStr = TRUE;
private const string FalseStr = FALSE;
public override bool CanConvert(Type objectType) => true;

//反序列化
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.ValueType == typeof(string))
{
if ((string)reader.Value == TrueStr)
{
return true;
}
else
{
return false;
}
}
return false;
}

//序列化
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value.GetType() == typeof(bool))
{
bool result = (bool)value;
if (result)
{
writer.WriteValue(TrueStr);
}
else
{
writer.WriteValue(FalseStr);
}
}
}
}

  然後,在需要操作的型別定義中的欄位/屬性中加入該特性:

private class MyClass
{
    [JsonConverter(typeof(MyBoolConverter))]
    public bool MyBool;
}

  此時:

string jsonStr = @"{""MyBool"": ""TRUE""}";
MyClass1 myClass = JsonConvert.DeserializeObject(jsonStr);
Console.WriteLine(myClass.MyBool);  //True
Console.WriteLine(JsonConvert.SerializeObject(myClass));  //{"MyBool":"TRUE"}

如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的認可是我寫作的最大動力!

贊(0)

分享創造快樂