在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<MyClass>(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时,需要自定义如下:

/// <summary>
/// 自定义布尔类型数据转换规则
/// </summary>
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<MyClass1>(jsonStr);
Console.WriteLine(myClass.MyBool);  //True
Console.WriteLine(JsonConvert.SerializeObject(myClass));  //{\"MyBool\":\"TRUE\"}

 

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!

作者:Minotauros
出处:https://www.cnblogs.com/minotauros/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

多语言业务错误日志收集监控工具Sentry 安装与使用

2020-11-9 5:02:59

随笔日记

迁移桌面程序到MS Store(8)——通过APPX下载Win32Component

2020-11-9 5:03:01

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索