c# 通过json.net中的JsonConverter进行自定义序列化与反序列化

  相信大家在工作中会经常遇见对json进行序列化与反序列化吧,但通常的序列化与反序列化中的json结构与c#中的类模型结构是相对应的,我们是否可以在序列化一个对象时候,让我们json的数据结构能按照自己的意愿,而不必与该对象的数据结构一样呢?,比如说,一个对象,只有一个名为"ID"的int类型的属性,值为1,如果序列化该对象,则能得到json:{"ID":1},但我现在希望得到的json的"ID"值是bool类型:{"ID":true}。要满足能够进行自定义序列化与反序列化的要求,我们可以运用json.net中的转换器JsonConverter。

  先来个简单的例子,就上面那个,一个对象,只有一个名为"ID"的int类型的属性,值为1,序列化该对象,如果ID值为1,则能得到json:{"ID":true},如果ID值不为1,得到json{"ID":false}。

  定义类:

        public class Model
        {
            public int ID { get; set; }
        }

  NuGet添加引用Newtonsoft.Json,再定义一个转换器类MyConverter,这个类要继承Newtonsoft.Json命名空间下的一个抽象类JsonConverter,我们先来看下这个抽象类的成员,有两个属性与三个抽象方法:

  

在MyConverter中我们要实现这三个抽象方法CanConvert()、ReadJson()、WriteJson(),并用特性[JsonConverter(typeof(MyConverter))]标记在我们要自定义序列化的类Model上就行了,就像这样:

  

        [JsonConverter(typeof(MyConverter))]
        public class Model
        {
            public int ID { get; set; }
        } 

  在序列化Model对象的时候,程序会走到MyConverter下已经实现的WriteJson()方法,同理,反序列化会走到ReadJson()方法,而CanConvert方法是用于判断是否需要自定义序列化或者反序列化的,它的参数objectType对应着特性JsonConverter所标记类的对应Type类型。

  下面是MyConverter类的代码实现:

  

        public class MyConverter : JsonConverter
        {
            //是否开启自定义反序列化,值为true时,反序列化时会走ReadJson方法,值为false时,不走ReadJson方法,而是默认的反序列化
            public override bool CanRead => false;
            //是否开启自定义序列化,值为true时,序列化时会走WriteJson方法,值为false时,不走WriteJson方法,而是默认的序列化
            public override bool CanWrite => true;

            public override bool CanConvert(Type objectType)
            {
                return typeof(Model) == objectType;
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                //new一个JObject对象,JObject可以像操作对象来操作json
                var jobj = new JObject();
                //value参数实际上是你要序列化的Model对象,所以此处直接强转
                var model = value as Model;
                if (model.ID != 1)
                {
                    //如果ID值为1,添加一个键位"ID",值为false
                    jobj.Add("ID",false);
                }
                else
                {
                    jobj.Add("ID", true);
                }
                //通过ToString()方法把JObject对象转换成json
                var jsonstr = jobj.ToString();
                //调用该方法,把json放进去,最终序列化Model对象的json就是jsonstr,由此,我们就能自定义的序列化对象了
                writer.WriteValue(jsonstr);
            }
        }    

  之后我们在Main函数里进行测试:

  

         static void Main(string[] args)
        {
            var model = new Model();
            model.ID = 1;
            var json = JsonConvert.SerializeObject(model);//由于ID值为1,得到json为{"ID":ture}

            Console.WriteLine(json);
            model.ID = 2;
            json = JsonConvert.SerializeObject(model);//由于ID值不为1,得到json为{"ID":false}
            Console.WriteLine(json);
            Console.ReadKey();
        }

  但是,还有一个问题,如果我们把json再反序列化为Model对象时会发生错误,因为json在反序列化为已经标记MyConverter的类Model时,MyConverter里面CanRead属性是false,反序列时是走默认反序列化,不走ReadJson()方法,json里ID属性是bool类型的,而Model里的ID属性是int类型。有三个方法可以解决:1、该模型只做序列化操作不做反序列化操作;2、新定义一个类,它的属性ID是bool类型;3、MyConverter中CanRead属性设为true,并实现ReadJson()方法。以下是第三种方法ReadJson()函数的实现:

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                var model = new Model();
                //获取JObject对象,该对象对应着我们要反序列化的json
                var jobj = serializer.Deserialize<JObject>(reader);
                //从JObject对象中获取键位ID的值
                var id = jobj.Value<bool>("ID");
                //根据id值判断,进行赋值操作
                if (id)
                {
                    model.ID = 1;
                }
                else
                {
                    model.ID = 0;
                }
                //最终返回的model对象就是json反序列化所得到的Model对象
                //主要,这里的model对象不一定非得是Model类型,ReadJson()方法与WriteJson()方法是一样的,可以自由操作反序列生成的对象或者序列化生成的json
                return model;
            }

  下面附上全部代码:

  

    class Program
    {
        static void Main(string[] args)
        {
            var model = new Model();
            model.ID = 1;
            var json = JsonConvert.SerializeObject(model);//由于ID值为1,得到json为{"ID":ture}
            var newModel = JsonConvert.DeserializeObject<Model>(json);//序列化得到的newModel对象ID值为1
        }

        [JsonConverter(typeof(MyConverter))]
        public class Model
        {
            public int ID { get; set; }
        }

        public class MyConverter : JsonConverter
        {
            //是否开启自定义反序列化,值为true时,反序列化时会走ReadJson方法,值为false时,不走ReadJson方法,而是默认的反序列化
            public override bool CanRead => true;
            //是否开启自定义序列化,值为true时,序列化时会走WriteJson方法,值为false时,不走WriteJson方法,而是默认的序列化
            public override bool CanWrite => true;

            public override bool CanConvert(Type objectType)
            {
                return typeof(Model) == objectType;
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                var model = new Model();
                //获取JObject对象,该对象对应着我们要反序列化的json
                var jobj = serializer.Deserialize<JObject>(reader);
                //从JObject对象中获取键位ID的值
                var id = jobj.Value<bool>("ID");
                //根据id值判断,进行赋值操作
                if (id)
                {
                    model.ID = 1;
                }
                else
                {
                    model.ID = 0;
                }
                //最终返回的model对象就是json反序列化所得到的Model对象
                //主要,这里的model对象不一定非得是Model类型,ReadJson方法与WriteJson方法是一样的,可以自由操作反序列生成的对象或者序列化生成的json
                return model;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                //new一个JObject对象,JObject可以像操作对象来操作json
                var jobj = new JObject();
                //value参数实际上是你要序列化的Model对象,所以此处直接强转
                var model = value as Model;
                if (model.ID != 1)
                {
                    //如果ID值为1,添加一个键位"ID",值为false
                    jobj.Add("ID",false);
                }
                else
                {
                    jobj.Add("ID", true);
                }
                //通过ToString()方法把JObject对象转换成json
                var jsonstr = jobj.ToString();
                //调用该方法,把json放进去,最终序列化Model对象的json就是jsonstr,由此,我们就能自定义的序列化对象了
                writer.WriteValue(jsonstr);
            }
        }
    }

  

原文地址:https://www.cnblogs.com/yijiayi/p/10051284.html

时间: 2024-07-28 19:18:47

c# 通过json.net中的JsonConverter进行自定义序列化与反序列化的相关文章

Json.Net学习(1) 实现简单的序列化和反序列化

Attributes 可以用来控制Json.Net如何序列化和反序列化.Net对象. >JsonObjectAttribute--标记在类上,用于控制该类如何被序列化为一个Json对象(JSON Object) >JsonArrayAttribute--标记在集合上,用于控制该集合如何被序列化为一个Json集合(JSON Array) >JsonPropertyAttribute--标记在字段和属性上,用于控制它如何被序列化为一个Json对象中的属性 >JsonConverterA

C#中,Json的序列化和反序列化的几种方式总结

什么是JSON? JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and easy for machines to parse and generate. JSON is a text format that is completely language independent. 翻译:Json[javascrip

在C#中,Json的序列化和反序列化的几种方式总结

在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 首先,解释一下json Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成,它是完全独立于语言的. Json支持下面两种数据结构: 键值对的集合--各种不同的编程语言,都支持这种数据结构: 有序的列表类型值的集合--这其中包含数组,集合,矢量,或者序列,等等. Json有下面几种表现形式 1.对象

Json.Net序列化和反序列化设置

首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.创建一个DataTable对象,如下: DataTable dt = new DataTable(); DataColumn dcName = new DataColumn("Name"); DataColumn dcAge = new DataColumn("Age");

Json的序列化与反序列化

想想某一天,你在看LOL攻略的时候,系统突然崩溃了,接着浏览器出现了密密麻麻的LOL帐号和密码,你一定在想:"天啊,这次要发财了,说不定里面有超凡号或者王者号,我得赶紧全部记下来."然而说完你就惊呆了,那么多的帐号密码,而且全部写在了Json里面,一个一个复制粘贴要记到什么时候啊...如果这时候我在你身边,我一定会帮助你的,前提是,要分几个王者号给我噢...  言归正传. 上面举的例子虽然有点不太现实,但其实是想和大家说明一个问题,如果要解析Json或XML,请不要使用检索字符串的方式

java中序列化与反序列化的冷知识

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 关于什么是序列化,和为什么要序列化的知识就不再阐述了,本文主要探讨一些特殊点的情况. 1.java中如何实现序列化和反序列化 下面的代码是进行序列化的简单实例 public static void main(String[] args) { System.out.println("-----------------序列化----------------------↓"); Student stu

Python 中数据的序列化和反序列化(json处理)

概念: JSON(JavaScript Object Notation):是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等). 这些

ASP.NET 中JSON 的序列化和反序列化

JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍,ASP.NET如何序列化和反序列化的处理,在序列化和反序列化对日期时间.集合.字典的处理. 一.JSON简介: JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大括号''{}'

**iOS发JSON请求中字符串加转义,返回的JSON去转义

iOS中使用NSSerialization把对象转为JSON字符串后,多出来反斜杠的问题 http://segmentfault.com/q/1010000000576646 NSDictionary *dic = @{@"url": @"http://..."}; NSLog(@"%@", dic); NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:N