一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化
想必大家在项目中都接触过 JSON 或者 XML 吧,为了将对象在网络上传输或者将其持久化必须将其序列化为一个字符串然后进行后续操作。常见的就是将其序列化成 JSON 或者 XML 。
大家在项目中应该都看到过这样的工具类 例如 ***XmlHelper、***JsonHelper 等,没错这一些助手类会帮助我们重复造轮子。既然是组件并且还是是开源的必须考虑每个功能的后续可扩展性以及易用性。
ISerializer 序列化者接口
using System; namespace Wlitsoft.Framework.Common.Abstractions.Serialize
{
/// <summary>
/// 序列化者接口。
/// </summary>
public interface ISerializer
{
/// <summary>
/// 获取序列化类型。
/// </summary>
SerializeType SerializeType { get; } /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
string Serialize(object obj); /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
object Deserialize(Type objType, string str); /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
T Deserialize<T>(string str);
}
}
该接口很简单就一个属性标示序列化类型、序列化方法、反序列化方法。
SerializeType 序列化类型
namespace Wlitsoft.Framework.Common.Abstractions.Serialize
{
/// <summary>
/// 序列化类型。
/// </summary>
public enum SerializeType
{
/// <summary>
/// Xml。
/// </summary>
Xml, /// <summary>
/// Json。
/// </summary>
Json
}
}
一个枚举标识使用哪种序列化方式。
类型有了那对应的原始的实现肯定少不了。

- JsonSerializer Json 序列化/反序列化。
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using Wlitsoft.Framework.Common.Abstractions.Serialize;
using Wlitsoft.Framework.Common.Exception; namespace Wlitsoft.Framework.Common.Serialize
{
/// <summary>
/// Json 序列化/反序列化。
/// </summary>
public class JsonSerializer : ISerializer
{
#region ISerializer 成员 /// <summary>
/// 获取序列化类型。
/// </summary>
public SerializeType SerializeType { get; } = SerializeType.Json; /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
public string Serialize(object obj)
{
#region 参数校验 if (obj == null)
throw new ObjectNullException(nameof(obj)); #endregion using (var ms = new MemoryStream())
{
new DataContractJsonSerializer(obj.GetType()).WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.ToArray());
} } /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public object Deserialize(Type objType, string str)
{
#region 参数校验 if (objType == null)
throw new ObjectNullException(nameof(objType)); if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
{
return new DataContractJsonSerializer(objType).ReadObject(ms);
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public T Deserialize<T>(string str)
{
#region 参数校验 if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion return (T)this.Deserialize(typeof(T), str);
} #endregion
}
}
JsonSerializer
- XmlSerializer Xml 序列化/反序列化。
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Wlitsoft.Framework.Common.Abstractions.Serialize;
using Wlitsoft.Framework.Common.Exception; namespace Wlitsoft.Framework.Common.Serialize
{
/// <summary>
/// Xml 序列化/反序列化。
/// </summary>
public class XmlSerializer : ISerializer
{
#region ISerializer 成员 /// <summary>
/// 获取序列化类型。
/// </summary>
public SerializeType SerializeType { get; } = SerializeType.Xml; /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
public string Serialize(object obj)
{
#region 参数校验 if (obj == null)
throw new ObjectNullException(nameof(obj)); #endregion System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); //去除默认的命名空间声明。
XmlSerializerNamespaces xmlNamespaces = new XmlSerializerNamespaces();
xmlNamespaces.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
settings.NewLineChars = "\r\n";
settings.IndentChars = " "; MemoryStream outStream = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(outStream, settings))
{
serializer.Serialize(writer, obj, xmlNamespaces);
} outStream.Position = ;
using (StreamReader reader = new StreamReader(outStream))
{
return reader.ReadToEnd();
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public object Deserialize(Type objType, string str)
{
#region 参数校验 if (objType == null)
throw new ObjectNullException(nameof(objType)); if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(objType);
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
{
using (StreamReader sr = new StreamReader(ms))
{
return mySerializer.Deserialize(sr);
}
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public T Deserialize<T>(string str)
{
#region 参数校验 if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion return (T)this.Deserialize(typeof(T), str);
} #endregion }
}
XmlSerializer
接口有了,对应的原生实现也有了,那咋用呢,还有我要不想用原生的Json 序列化方式咋办比如想用 JSON.Net 别急继续往下 See。
SerializerFactory 序列化工厂
把它定义成工厂确实有些牵强但是没有想到很好的名称 那就暂时先就叫工厂吧。它主要存储所有的序列化者对象实例、可以获取实例、亦可以重新设置实例。下面只列出方法签名。
/// <summary>
/// 获取一个 <see cref="ISerializer"/> 的实例。
/// </summary>
/// <param name="type">序列化类型。</param>
/// <returns>一个 <see cref="ISerializer"/> 类型的对象实例。</returns>
public ISerializer GetSerializer(SerializeType type)
/// <summary>
/// 获取一个 <see cref="ISerializer"/> 的实例。
/// </summary>
/// <param name="type">序列化类型。</param>
/// <returns>一个 <see cref="ISerializer"/> 类型的对象实例。</returns>
public ISerializer GetSerializer(SerializeType type)
现在可以使用了,等下 还没完。。。 为了更便于使用它们 将其做成 扩展方法。
ObjectExtensions 对象扩展方法静态类。
/// <summary>
/// 将 json 字符串转换为指定类型的对象表示形式。
/// </summary>
/// <typeparam name="T">要转换成的对象类型。</typeparam>
/// <param name="json">json 字符串。</param>
/// <returns>转换完后的 JSON 对象。</returns>
public static T ToJsonObject<T>(this string json)
{
#region 参数校验 if (string.IsNullOrEmpty(json))
throw new StringNullOrEmptyException(nameof(json)); #endregion ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
return serializer.Deserialize<T>(json);
}
/// <summary>
/// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
/// </summary>
/// <typeparam name="T">要转换成的对象类型。</typeparam>
/// <param name="xml">json 字符串。</param>
/// <returns>转换完后的 Xml 对象。</returns>
public static T ToXmlObject<T>(this string xml)
{
#region 参数校验 if (string.IsNullOrEmpty(xml))
throw new StringNullOrEmptyException(nameof(xml)); #endregion ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
return serializer.Deserialize<T>(xml);
}
StringExtensions 字符串类型扩展方法静态类。
/// <summary>
/// 将给定对象(<paramref name="obj"/>)转换成 JSON 字符串的表示形式。
/// </summary>
/// <param name="obj">准备进行转换的对象。</param>
/// <returns>转换后生成的 JSON 字符串。</returns>
public static string ToJsonString(this object obj)
{
#region 参数校验 if (obj == null)
throw new ObjectNullException(nameof(obj)); #endregion ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
return serializer.Serialize(obj);
}
/// <summary>
/// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
/// </summary>
/// <typeparam name="T">要转换成的对象类型。</typeparam>
/// <param name="xml">json 字符串。</param>
/// <returns>转换完后的 Xml 对象。</returns>
public static T ToXmlObject<T>(this string xml)
{
#region 参数校验 if (string.IsNullOrEmpty(xml))
throw new StringNullOrEmptyException(nameof(xml)); #endregion ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
return serializer.Deserialize<T>(xml);
}
关于扩展性
回到刚才那个问题,如果我不想用原生的 Json 序列化方式咋办,难不成字符串扩展以及对象扩展这些方法都用不了了吗。别急继续往下看。

Common.JsonNet.JsonSerializer 公共类库 Json.Net 组件序列化者。
该项目中 JsonNetJsonSerializer 实现了 ISerializer 接口,也就是说这个类有序列化和反序列化的能力,那类有了怎么用呢。
当然你可以直接 new 一个 JsonNetJsonSerializer 的实例 然后使用。但是这样的话就有点本末倒置了。
GlobalConfig 全局配置静态类
这个类中后续会有好多属性 可以修改 Common 包内部的一些实现方式。
比如:将 Common 包中原生的 Json 序列化实现用 JSON.Net 取缔只需要 在 网站的 Startup 或者 控制台中的 静态构造方法中写入下面一行代码即可。
GlobalConfig.SerializerFactory.SetSerializer(SerializeType.Json,new JsonNetJsonSerializer());
一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化的更多相关文章
- 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端
一个技术汪的开源梦 —— 目录 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 POST 了,那下面开 ...
- 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之目录结构
一个技术汪的开源梦 —— 目录 这篇文章是开源公共组件的开篇那就先说说项目的 Github 目录结构和 .Net Core 的项目结构. 1. GitHub 目录结构和相关文件 - src 源码项目目 ...
- 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 & 发布
一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...
- 一个技术汪的开源梦 —— 微信开发工具包(WeixinSDK)
由于春节的关系 WeixinSDK 这个开源项目的进展比预期推迟了大约一个月的时间,值得高兴的是到目前为止该项目的重要模块已经开发完毕. - 关于项目 该项目的背景是现在微信公众号.微信服务号乃至微 ...
- 一个技术汪的开源梦 —— 公共组件缓存之分布式缓存 Redis 实现篇
Redis 安装 & 配置 本测试环境将在 CentOS 7 x64 上安装最新版本的 Redis. 1. 运行以下命令安装 Redis $ wget http://download.redi ...
- 统一流控服务开源:基于.Net Core的流控服务
先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠.今天整理一下 ...
- 开源一个自己造的轮子:基于图的任务流引擎GraphScheduleEngine
GraphScheduleEngine是什么: GraphScheduleEngine是一个基于DAG图的任务流引擎,不同语言编写.运行于不同机器上的模块.程序,均可以通过订阅GraphSchedul ...
- prime 又一个开源的基于graphql 的cms
prime 是一个开源的基于graphql 的cms,类似的已经又好多了,strapi 就是一个(graphql 是通过插件扩展的) graphcms 是一款不错的,但是是收费的,prime 是基于t ...
- [PHP] 一个免费、开源的基于tp5+layui2.1.5开发的快速开发框架
推荐 一个免费.开源的基于tp5+layui2.1.5开发的快速开发框架,既可以用来学习,也可以用来实际项目的快速开发: 码云下载:https://gitee.com/eduaskcms/eduask ...
随机推荐
- (系统架构)标准Web系统的架构分层
标准Web系统的架构分层 1.架构体系分层图 在上图中我们描述了Web系统架构中的组成部分.并且给出了每一层常用的技术组件/服务实现.需要注意以下几点: 系统架构是灵活的,根据需求的不同,不一定每一层 ...
- Cocos2d Android 环境搭建
1.在开始之前,需要先准备好资源如下,如果安卓开发环境有了直接装第3.4. 1.JDK 点击下载 (1.6) 2.ADT(已经自带Android SDK)点击下载 3.NDK 点击下载 4. ...
- 博客使用BOS上传图片
1.博客平台的选定 从大学开始做个人主页算起,最开始是使用html,CSSS写简单的页面,后面大学毕业之后接触到了WordPress,就开始用WordPress搭建网站.现在还维护着一个农村网站.ht ...
- C#多线程之基础篇3
在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...
- mount报错: you must specify the filesystem type
在linux mount /dev/vdb 到 /home 分区时报错: # mount /dev/vdb /homemount: you must specify the filesystem ty ...
- 手机游戏渠道SDK接入工具项目分享(二)万事开头难
一般接到任务后程序员们通常都开始着手进行技术调研了,但我这活是项目负责人.还有一大堆事情要先期准备,没人能帮忙. 一.人力配置 考虑的之前已经有一波人搞了大半年,但没有起色,先期也没有太大人力需求,所 ...
- 机器学习之sklearn——EM
GMM计算更新∑k时,转置符号T应该放在倒数第二项(这样计算出来结果才是一个协方差矩阵) from sklearn.mixture import GMM GMM中score_samples函数第 ...
- 【Win10】UAP/UWP/通用 开发之 x:Bind
[Some information relates to pre-released product which may be substantially modified before it's co ...
- SAE+WordPress快速搭建个人博客
前些天一时冲动,买了个域名,我想总不能放着不用吧,干脆就搭建了一个个人博客.下面我把搭建的过程分享给大家.注意,此文并不是攻略,只是为了记录下这个从无到有的过程,当然,假如解决了你的疑惑,那当然是极好 ...
- Linux 中优秀的文本化编辑思想大碰撞(Markdown、LaTeX、MathJax)
这样一个标题可能不太准确,因为确实无法准确地解释什么叫"文本化编辑思想".其实我这篇随笔主要是想探讨 Markdown.LaTeX.MathJax,有兴趣的朋友可以继续往下看,同时 ...