Json.NET使用笔记


前言

本文是个人在工作中记录Json.NET使用笔记,简单的举例介绍了一下使用方法。


一、Json.NET是什么?

Json.Net是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单,并且开源。本人主要用到了自定义Json序列化的功能。
下载地址: 官网地址GitHub
官方文档: 官方API.

二、使用步骤

1. 引入

引入包的方式有多种,这里直接就使用NuGget导入包
NuGget导入

2. JsonConverter的使用

简介:继承JsonConverter重写其方法可以自定义属性的序列化方式。
随便生成一个类
代码如下:

 public class Student
    {
        public int Age;
        public Sex Sex;
        public string Name { get; set; }
    }

    public enum Sex
    {
        boy,
        girl
    }

2.1 直接序列化

尝试将该类进行Json序列化操作
代码如下:

	//1.将对象序列化为Json字符串
	Student mm = new Student() { Age = 3, Name = "MM", Sex = Sex.girl };
	string jsonStr = JsonConvert.SerializeObject(mm);
 	Console.WriteLine(jsonStr);

查看运行结果:
直接序列化结果
可以看到枚举类型被换成了int类型,传给前端可能不易理解。

2.2 构建转换器

接下来我们再新建一个类,并且继承JsonConverter,重写其方法。
代码如下:

	/// <summary>
    /// 自定义属性转换类
    /// </summary>
    public class SexCustomSerializable : JsonConverter
    {
        //表示反序列化时是否执行该转换器
        public override bool CanRead => true;

        //表示序列化时是否执行该转换器
        public override bool CanWrite => true;

        //判断执行条件(可以判断类型是否符合再执行转换)
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Sex);
        }

        //反序列化时执行的转换方法
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            Sex sex = Sex.boy;
            Enum.TryParse<Sex>(reader.Value.ToString(), out sex);
            return sex;
        }

        /// 序列化时执行的转换
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            //string v = value.ToString();
            writer.WriteValue(value.ToString());
        }
    }

2.3 使用转换器

转换器使用方法很简单,在对应的属性上加上标签即可
代码如下:

 public class Student
    {
        public int Age;

        [JsonConverter(typeof(SexCustomSerializable))]
        public Sex Sex;

        public string Name { get; set; }
    }

2.4 使用转换器序列化效果

查看运行结果:
效果图
可以看到枚举类型根据我们转换器重写的WriteJson方法toString输出了。
当然,如果只需要把枚举类型从int转换到String输出,Json.NET有封装好的转换器给我们用。

2.5 StringEnumConverter使用

代码如下:

 public class Student
    {
        public int Age;

        [JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }
    }

查看运行结果:
在这里插入图片描述
可以看到,效果是和我们写的是一样的。

3. JsonProperty与JsonIgnore的使用

简介:使用[JsonIgnore]标签可以是实体类在序列化时忽略该属性,[JsonProperty]与之相反。

3.1 JsonIgnore使用

实体类是默认会在Json序列化时,转换全部的属性,如果有不需要的可以打上[JsonIgnore]标签,其实默认的实体类会有[JsonObject(MemberSerialization.OptOut)]标签,表示转换全部属性。

 public class Student
    {
        [JsonIgnore]
        public int Age;

        [JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }
    }

结果:
图片描述

3.3 JsonProperty使用

[JsonProperty]与[JsonIgnore]效果相反,在有[JsonObject(MemberSerialization.OptIn)]的实体类里面指定属性转换。

[JsonObject(MemberSerialization.OptIn)]
 public class Student
    {
        [JsonProperty]
        public int Age;
		[JsonProperty]
        [JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }
    }

结果:
图片描述

3.4 JsonProperty序列化非公属性

 public class Student
    {
        //[JsonProperty]
        public int Age;

        //[JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }

        [JsonProperty]
        private DateTime born;

        public void SetBron(DateTime date)
        {
            born = date;
        }

        public DateTime GetBron()
        {
            return born;
        }
    }
			Student gg = new Student() { Age = 5, Sex = Sex.boy };
            gg.SetBron(DateTime.Now.ToLocalTime());
            Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                //添加性别枚举转换器
                setting.Converters.Add(new SexCustomSerializable());
                //对时间的处理
                setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                return setting;
            });

结果:
结果图

3.5 JsonProperty修改序列化属性名称

一般情况实体类都不能随意修改,在序列化与反序列化时可以自定义序列化出字符串的属性名称。
代码:

public class Student
    {
        //[JsonProperty]
        public int Age;

        //[JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }

        [JsonProperty(PropertyName = "BornDay")]
        private DateTime born;

        public void SetBron(DateTime date)
        {
            born = date;
        }

        public DateTime GetBron()
        {
            return born;
        }
    }
Student gg = new Student() { Age = 5, Sex = Sex.boy };
            gg.SetBron(DateTime.Now.ToLocalTime());
            Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();

            //JsonSerializerSettings setting = new JsonSerializerSettings();
            //string jsonStr = JsonConvert.Serializeobject(p, Newtonsoft.Json.Formatting.Indented, setting);
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                //添加性别枚举转换器
                setting.Converters.Add(new SexCustomSerializable());
                //对时间的处理
                setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                return setting;
            });
            string ggStr = JsonConvert.SerializeObject(gg);

结果:
图片描述

4. DefaultContractResolver的使用

简介:继承DefaultContractResolver类重写其方法,可以实现动态决定属性序列化。
这里新建一个StudentPropsContractResolver类继承DefaultContractResolver,并且重写其方法。
代码:

public class StudentPropsContractResolver : DefaultContractResolver
    {
        /// <summary>
        /// 需要处理的属性名
        /// </summary>
        private string[] props = null;

        /// <summary>
        /// 属性是否需要序列化
        /// (一般都是指定哪些属性不序列化的多,但这里加入该属性可以应对两种情况)
        /// </summary>
        private bool serialize;

        public StudentPropsContractResolver(string[] props, bool retain = true)
        {
            this.props = props;
            this.serialize = retain;
        }

        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            //原方法里面有注释,看不懂的也可以自己调试一下就明白参数都是啥了
            //获取类的属性
            IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
            //只保留数组中的属性
            return list.Where(p =>
            {
                if (serialize)
                {
                    return props.Contains(p.PropertyName);
                }
                else
                {
                    return !props.Contains(p.PropertyName);
                }
            }).ToList();
        }
    }

执行代码:

            //1.将对象序列化为Json字符串
            Student mm = new Student() { Age = 3, Name = "MM", Sex = Sex.girl };
            string jsonStr = JsonConvert.SerializeObject(mm);

            JsonSerializerSettings jsetting = new JsonSerializerSettings();
            jsetting.ContractResolver = new StudentPropsContractResolver(new string[] { "Age", "Sex" });
            Console.WriteLine(JsonConvert.SerializeObject(mm, jsetting));
            jsetting.ContractResolver = new StudentPropsContractResolver(new string[] { "Name", "Sex" });
            Console.WriteLine(JsonConvert.SerializeObject(mm, jsetting));
            Console.ReadLine();

结果:
运行效果
可以看到通过重写DefaultContractResolver方法可以实现动态决定属性序列化。

5. 通过JsonConvert.DefaultSettings全局设置

简介:有时候我们需要设置一下通用的规则,可以在JsonConvert.DefaultSettings不用再给每一个属性打标签了。

5.1 NullValueHandling的全局设置

在这里想把null的属性不序列化了。
代码:

Student gg = new Student() { Age = 5, Sex = Sex.boy };
            Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
            string ggStr = JsonConvert.SerializeObject(gg);
            Console.WriteLine(ggStr);
            Console.ReadLine();

结果:
效果图
可以看到name没有赋值输出了null,可能会给前端带了一些困扰,而且值也没有什么意义,当然也可以直接设置jsetting.NullValueHandling = NullValueHandling.Ignore来让空值不序列化。

 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
 public String Name { get; set; }

Json.Net提供了全局设置,方便我们操作。
代码:

			Student gg = new Student() { Age = 5, Sex = Sex.boy };
            Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                return setting;
            });
            string ggStr = JsonConvert.SerializeObject(gg);

效果:
效果图

5.2 Converters的全局设置

当然,默认设置不仅仅可以设置null不序列化,还可以把我们刚才创建的转换器添加到设置里。
代码:

 JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                //添加性别枚举转换器
                setting.Converters.Add(new SexCustomSerializable());
                return setting;
            });

实体类去除标签:

public class Student
    {
        //[JsonProperty]
        public int Age;

        //[JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }
    }

结果:

效果图
当然,还有对时间格式的处理
代码:

JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                //添加性别枚举转换器
                setting.Converters.Add(new SexCustomSerializable());
                //对时间的处理
                setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                return setting;
            });

结果:
结果图

6. 注意事项

前面也有说到实体类一般不会去动他,这个也包括打标签等操作,在实际开发中,一个实体类越简单越好。所以以下使用方法比较规范一些。
代码:

 public class Student
    {
        //[JsonProperty]
        public int Age;

        //[JsonConverter(typeof(StringEnumConverter))]
        public Sex Sex;

        public string Name { get; set; }

        //[JsonProperty(PropertyName = "BornDay")]
        private DateTime born;

        public void SetBron(DateTime date)
        {
            born = date;
        }

        public DateTime GetBron()
        {
            return born;
        }
    }
Student gg = new Student() { Age = 5, Sex = Sex.boy };
            gg.SetBron(DateTime.Now.ToLocalTime());
            Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;
                var contractResolver = new StudentPropsContractResolver(new string[] { "Age", "Sex", "bron" });
                contractResolver.IgnoreSerializableAttribute = true;
                setting.ContractResolver = contractResolver;
                //添加性别枚举转换器
                setting.Converters.Add(new SexCustomSerializable());
                //对时间的处理
                setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                return setting;
            });
            string ggStr = JsonConvert.SerializeObject(gg);

总结

Newtonsoft.Json序列化库提供了很多Json序列化有关的特性方便我们开发,学会使用是不难的,上面列举的只是一部分功能,更多的功能可以到官网文档进行学习。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
esp32使用json的步骤可以分为以下几步: 1. 引用中的方法,使用`deserializeJson`函数对接收到的json文件进行解析。该函数接受两个参数,第一个参数是建立的DynamicJsonDocument对象,第二个参数是获取到的json文件(类型为String)。 2. 根据引用中的内容,了解JSON的基础概念、语法规则和数据类型。JSON包括数字、字符串、逻辑值、数组和对象等数据类型。 3. 以引用中的解析JSON数据为例,可以使用`cJSON_Parse`函数将给定的JSON字符串转换为cJSON对象。 4. 使用相应的库函数来操作cJSON对象,例如使用`cJSON_GetObjectItem`函数根据键获取对应的值,使用`cJSON_GetArrayItem`函数根据下标获取cJSON对象数组中的对象,使用`cJSON_AddStringToObject`函数新增一个字符串类型的字段到JSON格式的数据等。 5. 在使用完cJSON对象后,使用`cJSON_Delete`函数释放链表占用的内存空间。 总结起来,使用ESP32处理JSON数据的过程包括解析JSON数据、操作cJSON对象以及释放内存空间等步骤。根据具体的需求和场景,可以使用不同的库函数来实现相应的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ESP32超详细学习记录:JSON解析(利用ArduinoJson库)](https://blog.csdn.net/qq_41650023/article/details/124668884)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【ESP32_8266_WiFi (九)】JSON基础](https://blog.csdn.net/K3169/article/details/127838227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [ESP8266学习笔记(8)——第三方库cJSON使用](https://blog.csdn.net/qq_36347513/article/details/86691835)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值