序列化对大家来说应该都不陌生,特别是现在大量使用WEBAPI,JSON满天飞,序列化操作应该经常出现在我们的代码上。

而我们最常用的序列化工具应该就是Newtonsoft.Json,当然你用其它工具类也是没问题的,我们重点讲的不是这个工具,我们的重点是高效的可自定义控制的序列化操作。

首先我们说一下大致的序列化原理:

一般情况下,我们把一个实体类,或是数据列表传给工具类(这里我拿Newtonsoft.Json做例子,其它的也是类似的)如:

class ClassTest{

public string aa{get;set;}

public string bb{get;set;}
}

var jsonStr=Newtonsoft.Json.JsonConvert.SerializeObject(new ClassTest());

得到的jsonStr="{\"aa\":null,\"bb\":null}";

这个时候我们就在想,序列化是怎么完成的呢,为什么我只要给他一个类,他就能帮我转化成一个JSON字符串呢?(应该有点开发年头的老鸟心里都有数,我还是多啰嗦几句,给新人看一下)

其实默认情况下它是使用了反射,当我们得到一个类,想知道它有什么成员,以及成员分别是什么值的时候,我们就只能用反射来得到,通过元数据我们能得到任何我们想要的信息(不了解反射的朋友可以去查一下相关资料),反射用起来确实很方便,但是有个很大的问题,就是性能,反射是相当耗性能的,下面我会讲到怎么样不用反射来实现序列化。

因为我们今天讲的重点是自定义,所以我们先来谈谈如何自定义。

默认情况下序列化工具会反射我们所有的属性,然后将它们转化到字符串中,如果我们只想让部分属性序列化出来要怎么做呢?

可能有人会说,那我再建立一个类,里面只写部分属性不就好了,虽然这也是一个办法,不过我相信大家都知道这个方法有多LOW,因为我们的需求是不断变化的,可能我们一个类要应付几十种场景,不可能我们每个场景都要新建一类吧,而且后期需求还会变动,还会增加,所以这个方案不行(如果你只想应付一下老板这个方法还是行的...)

可能又有人说,这些序列化工具类都提供了对应的特性,只要我写在我的属性身上我就可以控制哪些显示,哪些不显示,哪些有什么默认值了比如:

[JsonProperty]
[JsonIgnore]
[DefaultValue(30)]
但是我想说的是你还是不能解决我们刚刚说的问题,因为一个类特性你只能写一次,你这样做虽然比刚刚好了一点,但是应付多个场景依然不行。
我们想要的解决方案是可以由我们程序自由控制哪些类本次需要在序列化字符串中,哪些不需要,我们只需要一个类就可以解决所有场景的问题,自由控制。
于是乎我们找到了一个方案 使用 ISerializable ,用它我们可以完全自定义序列化过程中的具体行为,不再需要反射来帮我们,我们自己来实现序列化的细节,这是最高效,最自由的一种方式,但是它也有一个缺点
就是过于繁琐。还是拿上面的类来做个例子:

class ClassTest: ISerializable{

#region  json序列化 反序列化

/// <summary>序列化时调用</summary>

public virtual void GetObjectData(SerializationInfo s, StreamingContext c)
{

if(!string.IsNullOrEmpty(aa))  //这里可以使用任何条件来控制是否序列化

{s.AddValue("aa", aa);}

s.AddValue("bb", bb);

}

/// <summary>反序列化时操作</summary>
protected ClassTest(SerializationInfo s, StreamingContext c)
{
SerializationInfoEnumerator sItem = s.GetEnumerator();
while (sItem.MoveNext())
{
switch (sItem.Name)
{
case "aa": aa = s.GetString("aa"); break;
case "bb": bb = s.GetString("bb"); break;

default: break;
}
}
}

#endregion

public string aa{get;set;}

public string bb{get;set;}
}

只需要继承这个接口,实现两个方法,就可以完全的自定义序列化过程了
可能又有人说你这里只说了JSON,还有XML序列化怎么办呢?不要急,XML也可以自定义,只要实现 IXmlSerializable,同样实现它里面定义的方法就可以了,我这里就不详细说了。
我们这样做了以后序列化的时候它就不会使用反射了,而是直接调用相应的接口方法,这样性能显著提高,同时你又可以根据自己的情况自定义序列的规则。
那我们刚刚说了它有一个缺点就是写起来太繁琐了,那我们怎么办呢,其实我是一直都有代码生成器,我写好了模版只要设计好数据库模型,我的实体类就自动生成出来了,根本不需要打任何代码,所以对我来说也不繁琐.
还有一个问题大家应该注意到了就是我所有的序列化判断是在类的方法里面写的,如果我想在外部调用的时候来控制哪些字段序列化,哪些不序列化怎么办呢,你这个也解决不了啊?
对,上面的例子确实解决不了,但是我还是有解决方案,我利用泛型把实体类做了改造,这样我就可以完全在外部来控制序列化了,这个具体的实现我会在后期的文章中在介绍我自己设计的开发框架时再详细说(如果大家有兴趣看的话)
说了半天好像完全没提到.NET core,现在要说它了,上面好个方案是可以用到之前的.net framework的各版本的,以及mono上也是可以运行的,但是现在最新的.NET core 就有点问题了,我最近想把我的开发框架
移植到.NET core上就出现了问题,它不支持ISerializable,本来我还以为是我用错了,后来查看了源码才发现是真的还不支持

因为.NET core才正式发布没多久,很多东西还不不是很完善,我在查这个问题的时候也是找了半天原因,所以我在这里也是给大家提个醒,这个东西暂时还没弄好,不过后面应该会弄好的,时间问题。

那么现阶段我们要怎么处理呢,其实很简单,既然序列化是把我们的类属生拼接成一个字符串,为什么我们不自己实现这个方法呢,只要用代码生成器帮我们生成这段代码,对我们来说也是很方便,高效的,应该说比以上方法都要高效。比如:


class ClassTest{


public string aa{get;set;}


public string bb{get;set;}

public string ToJson()

{

System.Text.StringBuilder sb = new System.Text.StringBuilder("{");

if(!string.IsNullOrEmpty(aa))  //这里可以使用任何条件来控制是否序列化

{sb.AppendFormat(",\"aa\":{0}", aa);}

sb.AppendFormat(",\"bb\":{0}", bb);

sb.Append("}");
return sb.ToString();

}

}

就这样写个方法就可以了,需要用到序列化的地方只需要用 new ClassTest().ToJson()就可以了,这样也很方便吧,同样的你想要外部调用时使用哪些序列化,后期我会再详细讲
其实小弟第一次发博客写文章,写的东西也很简单,没什么太大的技术含量,希望各位大神,大虾指点我的时候轻点拍砖,我也只是把我知道的一直在用的,感觉比较好用的分享出来而以,并不是来秀技术的,我也没什么技术好秀。
以上内容,完全手打原创,转载请注明出处!望各位大神指错!

.Net Core 自定义序列化格式的更多相关文章

  1. Newtonsoft.Json 自定义序列化格式转化器

    public static class JsonHelper { static JsonHelper() { Newtonsoft.Json.JsonSerializerSettings settin ...

  2. Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  3. 使用Typescript重构axios(二十八)——自定义序列化请求参数

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  4. fastjson自定义序列化竟然有这么多姿势?

    本文介绍下fastjson自定义序列化的各种操作. 一.什么是fastjson? fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSO ...

  5. Gorm 预加载及输出处理(三)- 自定义时间格式

    前言 Gorm 中 time.Time 类型的字段在 JSON 序列化后呈现的格式为 "2020-03-11T18:26:13+08:00",在 Go 标准库文档 - time 的 ...

  6. Hive中自定义序列化器(带编码)

    hive SerDe的简介 https://www.jianshu.com/p/afee9acba686 问题 数据文件为文本文件,每一行为固定格式,每一列的长度都是定长或是有限制范围,考虑采用hiv ...

  7. POI对Excel自定义日期格式的读取

    用POI读取Excel数据:(版本号:POI3.7) 1.读取Excel private List<String[]> rosolveFile(InputStream is, String ...

  8. java中使用poi导入导出excel文件_并自定义日期格式

    Apache POI项目的使命是创造和保持java API操纵各种文件格式基于Office Open XML标准(OOXML)和微软的OLE复合文档格式(OLE2)2.总之,你可以读写Excel文件使 ...

  9. PHP序列化以及反序列化系列[1]--PHP序列化格式的写法

    反序列化:对单一的已序列化的变量进行操作,将其转换回 PHP 的值(zval). PHP序列化方式 PHP在序列化的时候会将相应的变量以对应的键值进行储存. 将一个类序列化的话,处理代码主要的 文件: ...

随机推荐

  1. 按要求编写Java应用程序。 (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。

    package zuoye; public class Cat { String name="妮妮"; String color="灰色"; int age=1 ...

  2. 0008《SQL必知必会》笔记04-子查询、联接与组合查询

    1.子查询:就是嵌套的查询,用一个查询的结果作为另一个查询的条件. 比如要列出订购了物品“RGAN01”的所有顾客的ID.姓名和联系人,需要经历以下几步 (1)从orderitems中找出订购了“RG ...

  3. 烂泥:vcenter5.5无AD下的安装与配置

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb. 公司现在的虚拟化使用的基本上都是vsphere,目前大约有7台物理机,为了更好的管理虚 ...

  4. 初识Hadoop入门介绍

    初识hadoop入门介绍 Hadoop一直是我想学习的技术,正巧最近项目组要做电子商城,我就开始研究Hadoop,虽然最后鉴定Hadoop不适用我们的项目,但是我会继续研究下去,技多不压身. < ...

  5. python setuptools工具打包

    http://blog.csdn.net/five3/article/details/7847551http://blog.csdn.net/reyoung1110/article/details/7 ...

  6. JavaScript日期控件,用select实现

    <!doctype html> <html> <head> <title>年月日</title> </head> <bod ...

  7. 调用newtonsoft.json反序列出错

    调用newtonsoft.json反序列出错: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current J ...

  8. java 22 - 16 多线程之生产者和消费者的问题

    生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获 ...

  9. 转:Git 求生手册 - 第三章分支工作

    from:http://newbranch.cn/zhi-zuo-fen-zhi-lai-gong-zuo-git-gh-pages-branching/ 来自:片段 实战 说了这么一大堆分支的东西. ...

  10. poj[2392]space elevator

    Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...