C# | 使用Json序列化对象时忽略只读的属性

简介: 将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。

image.png

C# 使用Json序列化对象时忽略只读的属性

@[toc]

前言

将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。
在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。
本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。


示例

修改前

创建一个student类型,包含四个属性,分别是ID,名称,生日和年龄。
其中年龄是根据生日计算得出的,是一个只读的属性。
使用序列化时的默认配置,编代码如下:嗯

    public class Student
    {
   
   
        public int Id {
   
    get; set; }
        public string Name {
   
    get; set; }
        public DateTime Birthday {
   
    get; set; }
        public int Age => DateTime.Now.Year - Birthday.Year;
    }

    internal class Program
    {
   
   
        static void Main(string[] args)
        {
   
   
            Student student = new Student()
            {
   
   
                Id = 1,
                Name = "张三",
                Birthday = DateTime.Parse("2008-08-08"),
            };

            Console.WriteLine(JsonConvert.SerializeObject(student,Formatting.Indented));
            Console.Read();
        }
    }

执行结果如下图所示,可以看到,只读的年龄属性也被序列化到了Json字符串中。
在这里插入图片描述

修改后

第一步:创建一个用于过滤只读属性的ContractResolver;
第二步:在序列化之前,创建一个Json序列化配置对象,并将刚才编写的ContractResolver放入配置中;
第三步:执行序列化是传入配置对象;

完整代码如下所示:

    public class Student
    {
   
   
        public int Id {
   
    get; set; }
        public string Name {
   
    get; set; }
        public DateTime Birthday {
   
    get; set; }
        public int Age => DateTime.Now.Year - Birthday.Year;
    }

    internal class Program
    {
   
   
        static void Main(string[] args)
        {
   
   
            Student student = new Student()
            {
   
   
                Id = 1,
                Name = "张三",
                Birthday = DateTime.Parse("2008-08-08"),
            };

            var settings = new JsonSerializerSettings()
            {
   
   
                ContractResolver = new WritablePropertiesOnlyResolver()
            };

            Console.WriteLine(JsonConvert.SerializeObject(student, Formatting.Indented, settings));
            Console.Read();
        }
    }

    class WritablePropertiesOnlyResolver : DefaultContractResolver
    {
   
   
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
   
   
            IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
            return props.Where(p => p.Writable).ToList();
        }
    }

运行结果如下:
在这里插入图片描述
至此,我们成功过滤了所有的只读属性。

相关文章
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
109 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
116 1
|
2月前
|
XML JSON 编解码
从JSON到Protobuf,深入序列化方案的选型与原理
序列化是数据跨边界传输的“翻译官”,将结构化数据转为二进制流。JSON可读性强但冗余大,Protobuf高效紧凑、性能优越,成主流选择。不同场景需权衡标准化与定制优化,选最合适方案。
238 3
|
4月前
|
JSON 人工智能 Go
在Golang中序列化JSON字符串的教程
在Golang中,使用`json.Marshal()`可将数据结构序列化为JSON格式。若直接对JSON字符串进行序列化,会因转义字符导致错误。解决方案包括使用`[]byte`或`json.RawMessage()`来避免双引号被转义,从而正确实现JSON的序列化与反序列化。
189 7
|
5月前
|
JSON IDE Java
鸿蒙开发:json转对象插件回来了
首先,我重新编译了插件,进行了上传,大家可以下载最新的安装包进行体验了,还是和以前一样,提供了在线版和IDE插件版,两个选择,最新的版本,除了升级了版本,兼容了最新的DevEco Studio ,还做了一层优化,就是针对嵌套对象和属性的生成,使用方式呢,一年前的文章中有过详细的概述,这里呢也简单介绍一下。
182 4
鸿蒙开发:json转对象插件回来了
|
5月前
|
XML JSON Java
go语言之JSON序列化
本文介绍了Go语言中的JSON序列化与反序列化,其操作与Java类似。需要注意的是,由于Go语言的包管理机制,变量和引入包的首字母需大写,以便其他包引用。示例代码展示了如何将`Student`结构体进行JSON序列化(返回字节数组,需转为字符串)及反序列化。此外,文章还说明了通过tag(如`json`和`xml`)指定序列化变量的重要性,以避免因包间访问限制导致反序列化失败或值为null的问题。
|
6月前
|
JSON JavaScript 前端开发
Go语言JSON 序列化与反序列化 -《Go语言实战指南》
本文介绍了 Go 语言中使用 `encoding/json` 包实现 JSON 与数据结构之间的转换。内容涵盖序列化(`Marshal`)和反序列化(`Unmarshal`),包括基本示例、结构体字段标签的使用、控制字段行为的标签(如 `omitempty` 和 `-`)、处理 `map` 和切片、嵌套结构体序列化、反序列化未知结构(使用 `map[string]interface{}`)以及 JSON 数组的解析。最后通过表格总结了序列化与反序列化的方法及类型要求,帮助开发者快速掌握 JSON 数据处理技巧。
|
11月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
780 12
|
12月前
|
JSON JavaScript 前端开发
Go语言中json序列化的一个小坑,建议多留意一下
在Go语言开发中,JSON因其简洁和广泛的兼容性而常用于数据交换,但其在处理数字类型时存在精度问题。本文探讨了JSON序列化的一些局限性,并介绍了两种替代方案:Go特有的gob二进制协议,以及msgpack,两者都能有效解决类型保持和性能优化的问题。
322 7
|
12月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
314 4