.Net Core 自定义序列化格式
序列化对大家来说应该都不陌生,特别是现在大量使用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 自定义序列化格式的更多相关文章
- Newtonsoft.Json 自定义序列化格式转化器
public static class JsonHelper { static JsonHelper() { Newtonsoft.Json.JsonSerializerSettings settin ...
- Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- 使用Typescript重构axios(二十八)——自定义序列化请求参数
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- fastjson自定义序列化竟然有这么多姿势?
本文介绍下fastjson自定义序列化的各种操作. 一.什么是fastjson? fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSO ...
- Gorm 预加载及输出处理(三)- 自定义时间格式
前言 Gorm 中 time.Time 类型的字段在 JSON 序列化后呈现的格式为 "2020-03-11T18:26:13+08:00",在 Go 标准库文档 - time 的 ...
- Hive中自定义序列化器(带编码)
hive SerDe的简介 https://www.jianshu.com/p/afee9acba686 问题 数据文件为文本文件,每一行为固定格式,每一列的长度都是定长或是有限制范围,考虑采用hiv ...
- POI对Excel自定义日期格式的读取
用POI读取Excel数据:(版本号:POI3.7) 1.读取Excel private List<String[]> rosolveFile(InputStream is, String ...
- java中使用poi导入导出excel文件_并自定义日期格式
Apache POI项目的使命是创造和保持java API操纵各种文件格式基于Office Open XML标准(OOXML)和微软的OLE复合文档格式(OLE2)2.总之,你可以读写Excel文件使 ...
- PHP序列化以及反序列化系列[1]--PHP序列化格式的写法
反序列化:对单一的已序列化的变量进行操作,将其转换回 PHP 的值(zval). PHP序列化方式 PHP在序列化的时候会将相应的变量以对应的键值进行储存. 将一个类序列化的话,处理代码主要的 文件: ...
随机推荐
- 磁带机Media is unrecognized
早晨检查磁带备份作业时,发现有个驱动的作业一直处于"Queue"状态,检查发现驱动有磁带,在Alert里面发现出现下面"Media is unrecognized&quo ...
- Javascript之旅——终点站:困惑的settimeout
有时候结局不是很美好,但起码这也算是一种结局,这个系列的最后一篇settimeout,这是一个让人困惑的函数,也是我一直在吐槽JS的 原因,我们看不到JS的源代码,setimeout同样也是,从始到终 ...
- 挖一挖C#中那些我们不常用的东西之系列(5)——FlagAttribute
说到FlagsAttribute,源自前几天看到了一小段代码,大概意思就是根据航班政策来返回哪些配送方式是否可用,根据这些是否可用 来隐藏或者开启界面的相关配送方式,如果大家订过机票可能知道配送方式有 ...
- Servlet/JSP-07 Session应用
Session应用 一. 避免表单重复提交 1. 表单重复提交的情况 ①在表单提交到一个 Servlet,而 Servlet 又通过请求转发的方式响应了一个 JSP 或者 HTML 页面,此时浏览器地 ...
- 多元线性回归 ——模型、估计、检验与预测
一.模型假设 传统多元线性回归模型 最重要的假设的原理为: 1. 自变量和因变量之间存在多元线性关系,因变量y能够被x1,x2-.x{k}完全地线性解释:2.不能被解释的部分则为纯粹的无法观测到的误差 ...
- 讲讲js中的逻辑与(&&)以及逻辑或(||)
前几天看到一个函数,百思不得其解,今天早上醒来看了本js的书,正好讲到操作符的用法,给大家分享下js中的&&,||,和我们用的其他的编程语言还是有点区别的. 直接上那个函数的代码: f ...
- 聚合及UML表示
聚合聚合是一种特别类型的关联,用于描述“总体到局部”的关系. 聚合分成: 基本聚合与合成聚合 基本聚合: 基本聚合一般也简称为聚合(Aggregation).在基本的聚合关系中, 部分类(B) ...
- tcp选项TCP_DEFER_ACCEPT
tcp选项TCP_DEFER_ACCEPT http://blog.chinaunix.net/uid-23207633-id-274317.html 之前在项目测试的时候,如果第三次握手发完裸ack ...
- C# RGB和HSB相互转换
背景 最近做的项目中有这样一个场景,设置任意一种颜色,得到这种颜色偏深和偏浅的两种颜色.也就是说取该颜色同色系的深浅两种颜色.首先想到的是调节透明度,但效果不理想.后来尝试调节颜色亮度,发现这才是正解 ...
- AWS国际版的Route 53和CloudFront
注册AWS国际版账号后,却发现Route 53和CloudFront功能是无法使用的.于是提交了一个Service Request,得到的答复是这两个功能需要验证后才能激活. 在控制台中点击进入Rou ...
