一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化

一个技术汪的开源梦 —— 目录

想必大家在项目中都接触过 JSON 或者 XML 吧,为了将对象在网络上传输或者将其持久化必须将其序列化为一个字符串然后进行后续操作。常见的就是将其序列化成 JSON 或者 XML 。

大家在项目中应该都看到过这样的工具类 例如 ***XmlHelper、***JsonHelper 等,没错这一些助手类会帮助我们重复造轮子。既然是组件并且还是是开源的必须考虑每个功能的后续可扩展性以及易用性。

ISerializer 序列化者接口

 1 using System;
 2
 3 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
 4 {
 5     /// <summary>
 6     /// 序列化者接口。
 7     /// </summary>
 8     public interface ISerializer
 9     {
10         /// <summary>
11         /// 获取序列化类型。
12         /// </summary>
13         SerializeType SerializeType { get; }
14
15         /// <summary>
16         /// 将一个对象序列化成一个字符串。
17         /// </summary>
18         /// <param name="obj">要序列化的对象。</param>
19         /// <returns>序列化后的字符串。</returns>
20         string Serialize(object obj);
21
22         /// <summary>
23         /// 将一个字符串反序列化为一个对象。
24         /// </summary>
25         /// <param name="objType">要反序序列化的对象类型。</param>
26         /// <param name="str">要反序列化的字符串。</param>
27         /// <returns>反序列化得到的对象。</returns>
28         object Deserialize(Type objType, string str);
29
30         /// <summary>
31         /// 将一个字符串反序列化为一个对象。
32         /// </summary>
33         /// <param name="str">要反序列化的字符串。</param>
34         /// <returns>反序列化得到的对象。</returns>
35         T Deserialize<T>(string str);
36     }
37 }

该接口很简单就一个属性标示序列化类型、序列化方法、反序列化方法。

SerializeType 序列化类型

 1 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
 2 {
 3     /// <summary>
 4     /// 序列化类型。
 5     /// </summary>
 6     public enum SerializeType
 7     {
 8         /// <summary>
 9         /// Xml。
10         /// </summary>
11         Xml,
12
13         /// <summary>
14         /// Json。
15         /// </summary>
16         Json
17     }
18 }

一个枚举标识使用哪种序列化方式。

类型有了那对应的原始的实现肯定少不了。

- JsonSerializer Json 序列化/反序列化。

 1 using System;
 2 using System.IO;
 3 using System.Runtime.Serialization.Json;
 4 using System.Text;
 5 using Wlitsoft.Framework.Common.Abstractions.Serialize;
 6 using Wlitsoft.Framework.Common.Exception;
 7
 8 namespace Wlitsoft.Framework.Common.Serialize
 9 {
10     /// <summary>
11     /// Json 序列化/反序列化。
12     /// </summary>
13     public class JsonSerializer : ISerializer
14     {
15         #region ISerializer 成员
16
17         /// <summary>
18         /// 获取序列化类型。
19         /// </summary>
20         public SerializeType SerializeType { get; } = SerializeType.Json;
21
22         /// <summary>
23         /// 将一个对象序列化成一个字符串。
24         /// </summary>
25         /// <param name="obj">要序列化的对象。</param>
26         /// <returns>序列化后的字符串。</returns>
27         public string Serialize(object obj)
28         {
29             #region  参数校验
30
31             if (obj == null)
32                 throw new ObjectNullException(nameof(obj));
33
34             #endregion
35
36             using (var ms = new MemoryStream())
37             {
38                 new DataContractJsonSerializer(obj.GetType()).WriteObject(ms, obj);
39                 return Encoding.UTF8.GetString(ms.ToArray());
40             }
41
42         }
43
44         /// <summary>
45         /// 将一个字符串反序列化为一个对象。
46         /// </summary>
47         /// <param name="objType">要反序序列化的对象类型。</param>
48         /// <param name="str">要反序列化的字符串。</param>
49         /// <returns>反序列化得到的对象。</returns>
50         public object Deserialize(Type objType, string str)
51         {
52             #region 参数校验
53
54             if (objType == null)
55                 throw new ObjectNullException(nameof(objType));
56
57             if (string.IsNullOrEmpty(str))
58                 throw new StringNullOrEmptyException(nameof(str));
59
60             #endregion
61
62             using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
63             {
64                 return new DataContractJsonSerializer(objType).ReadObject(ms);
65             }
66         }
67
68         /// <summary>
69         /// 将一个字符串反序列化为一个对象。
70         /// </summary>
71         /// <param name="str">要反序列化的字符串。</param>
72         /// <returns>反序列化得到的对象。</returns>
73         public T Deserialize<T>(string str)
74         {
75             #region 参数校验
76
77             if (string.IsNullOrEmpty(str))
78                 throw new StringNullOrEmptyException(nameof(str));
79
80             #endregion
81
82             return (T)this.Deserialize(typeof(T), str);
83         }
84
85         #endregion
86     }
87 }

JsonSerializer

- XmlSerializer Xml 序列化/反序列化。

  1 using System;
  2 using System.IO;
  3 using System.Text;
  4 using System.Xml;
  5 using System.Xml.Serialization;
  6 using Wlitsoft.Framework.Common.Abstractions.Serialize;
  7 using Wlitsoft.Framework.Common.Exception;
  8
  9 namespace Wlitsoft.Framework.Common.Serialize
 10 {
 11     /// <summary>
 12     /// Xml 序列化/反序列化。
 13     /// </summary>
 14     public class XmlSerializer : ISerializer
 15     {
 16         #region ISerializer 成员
 17
 18         /// <summary>
 19         /// 获取序列化类型。
 20         /// </summary>
 21         public SerializeType SerializeType { get; } = SerializeType.Xml;
 22
 23         /// <summary>
 24         /// 将一个对象序列化成一个字符串。
 25         /// </summary>
 26         /// <param name="obj">要序列化的对象。</param>
 27         /// <returns>序列化后的字符串。</returns>
 28         public string Serialize(object obj)
 29         {
 30             #region  参数校验
 31
 32             if (obj == null)
 33                 throw new ObjectNullException(nameof(obj));
 34
 35             #endregion
 36
 37             System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
 38
 39             //去除默认的命名空间声明。
 40             XmlSerializerNamespaces xmlNamespaces = new XmlSerializerNamespaces();
 41             xmlNamespaces.Add("", "");
 42
 43             XmlWriterSettings settings = new XmlWriterSettings();
 44             settings.OmitXmlDeclaration = true;
 45             settings.Indent = true;
 46             settings.NewLineChars = "\r\n";
 47             settings.IndentChars = "    ";
 48
 49             MemoryStream outStream = new MemoryStream();
 50             using (XmlWriter writer = XmlWriter.Create(outStream, settings))
 51             {
 52                 serializer.Serialize(writer, obj, xmlNamespaces);
 53             }
 54
 55             outStream.Position = 0;
 56             using (StreamReader reader = new StreamReader(outStream))
 57             {
 58                 return reader.ReadToEnd();
 59             }
 60         }
 61
 62         /// <summary>
 63         /// 将一个字符串反序列化为一个对象。
 64         /// </summary>
 65         /// <param name="objType">要反序序列化的对象类型。</param>
 66         /// <param name="str">要反序列化的字符串。</param>
 67         /// <returns>反序列化得到的对象。</returns>
 68         public object Deserialize(Type objType, string str)
 69         {
 70             #region 参数校验
 71
 72             if (objType == null)
 73                 throw new ObjectNullException(nameof(objType));
 74
 75             if (string.IsNullOrEmpty(str))
 76                 throw new StringNullOrEmptyException(nameof(str));
 77
 78             #endregion
 79
 80             System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(objType);
 81             using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
 82             {
 83                 using (StreamReader sr = new StreamReader(ms))
 84                 {
 85                     return mySerializer.Deserialize(sr);
 86                 }
 87             }
 88         }
 89
 90         /// <summary>
 91         /// 将一个字符串反序列化为一个对象。
 92         /// </summary>
 93         /// <param name="str">要反序列化的字符串。</param>
 94         /// <returns>反序列化得到的对象。</returns>
 95         public T Deserialize<T>(string str)
 96         {
 97             #region 参数校验
 98
 99             if (string.IsNullOrEmpty(str))
100                 throw new StringNullOrEmptyException(nameof(str));
101
102             #endregion
103
104             return (T)this.Deserialize(typeof(T), str);
105         }
106
107         #endregion
108
109     }
110 }

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 对象扩展方法静态类。

 1 /// <summary>
 2 /// 将 json 字符串转换为指定类型的对象表示形式。
 3 /// </summary>
 4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
 5 /// <param name="json">json 字符串。</param>
 6 /// <returns>转换完后的 JSON 对象。</returns>
 7 public static T ToJsonObject<T>(this string json)
 8 {
 9     #region 参数校验
10
11     if (string.IsNullOrEmpty(json))
12         throw new StringNullOrEmptyException(nameof(json));
13
14     #endregion
15
16     ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
17     return serializer.Deserialize<T>(json);
18 }
 1 /// <summary>
 2 /// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
 3 /// </summary>
 4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
 5 /// <param name="xml">json 字符串。</param>
 6 /// <returns>转换完后的 Xml 对象。</returns>
 7 public static T ToXmlObject<T>(this string xml)
 8 {
 9     #region 参数校验
10
11     if (string.IsNullOrEmpty(xml))
12         throw new StringNullOrEmptyException(nameof(xml));
13
14     #endregion
15
16     ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
17     return serializer.Deserialize<T>(xml);
18 }

StringExtensions 字符串类型扩展方法静态类。

 1 /// <summary>
 2 /// 将给定对象(<paramref name="obj"/>)转换成 JSON 字符串的表示形式。
 3 /// </summary>
 4 /// <param name="obj">准备进行转换的对象。</param>
 5 /// <returns>转换后生成的 JSON 字符串。</returns>
 6 public static string ToJsonString(this object obj)
 7 {
 8     #region 参数校验
 9
10     if (obj == null)
11         throw new ObjectNullException(nameof(obj));
12
13     #endregion
14
15     ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
16     return serializer.Serialize(obj);
17 }
 1 /// <summary>
 2 /// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
 3 /// </summary>
 4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
 5 /// <param name="xml">json 字符串。</param>
 6 /// <returns>转换完后的 Xml 对象。</returns>
 7 public static T ToXmlObject<T>(this string xml)
 8 {
 9     #region 参数校验
10
11     if (string.IsNullOrEmpty(xml))
12         throw new StringNullOrEmptyException(nameof(xml));
13
14     #endregion
15
16     ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
17     return serializer.Deserialize<T>(xml);
18 }

关于扩展性

回到刚才那个问题,如果我不想用原生的 Json 序列化方式咋办,难不成字符串扩展以及对象扩展这些方法都用不了了吗。别急继续往下看。

Common.JsonNet.JsonSerializer 公共类库 Json.Net 组件序列化者。

该项目中  JsonNetJsonSerializer  实现了  ISerializer 接口,也就是说这个类有序列化和反序列化的能力,那类有了怎么用呢。

当然你可以直接 new 一个 JsonNetJsonSerializer 的实例 然后使用。但是这样的话就有点本末倒置了。

GlobalConfig 全局配置静态类

这个类中后续会有好多属性 可以修改 Common 包内部的一些实现方式。

比如:将 Common 包中原生的 Json 序列化实现用 JSON.Net 取缔只需要 在 网站的 Startup 或者 控制台中的 静态构造方法中写入下面一行代码即可。

1 GlobalConfig.SerializerFactory.SetSerializer(SerializeType.Json,new JsonNetJsonSerializer());

未完待续。

下篇预告:一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端。

一个技术汪的开源梦 —— 目录

时间: 2024-10-20 17:51:20

一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化的相关文章

一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端

一个技术汪的开源梦 —— 目录 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 POST 了,那下面开始讲解对于 Http 请求客户端的简单封装. 首先,说一个好消息 就是 .Net Core 已将之前的 System.Net.Http 组件默认添加到了 NETStandard.Library 库中,所以直接用就好了,不需要再额外在 Nuget 上安装了,说道 Nuget 后续计划会有一篇文章介绍

一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之目录结构

一个技术汪的开源梦 —— 目录 这篇文章是开源公共组件的开篇那就先说说项目的 Github 目录结构和 .Net Core 的项目结构. 1. GitHub 目录结构和相关文件 - src 源码项目目录. - test 单元测试项目目录. - tools 工具目录. - .gitignore 你想要忽略的文件或者目录(一些文件诸如 *.dll.testResults 等 不需要提交到 github 上的文件)详情:https://git-scm.com/docs/gitignore. - .gi

一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 &amp; 发布

微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 Nuget 包和发布. 之前 .Net Framework 程序集打包 Nuget 有以下方法: 1. 使用命令  nuget pack  详见博客园的一篇博文 <用命令行工具创建 Nuget 程序包>: 2. 使用 NuGet Package Explorer: 3. vs 插件 NuBuild Project System.

统一流控服务开源:基于.Net Core的流控服务

原文:统一流控服务开源:基于.Net Core的流控服务 先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠.今天整理一下核心设计和实现思路,开源到Github上,分享给大家 https://github.com/zhouguoqing/FlowControl  一.令牌桶算法实现 先回顾一下令牌桶算法示意图 随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=10

Orchard 基于 ASP.NET MVC 技术的免费开源内容管理系统

Orchard 是由微软公司创建,基于 ASP.NET MVC 技术的免费开源内容管理系统: 可用于建设博客.新闻门户.企业门户.行业网站门户等各种网站 简单易用的后台界面 性能稳定,功能齐全 热拔插模块化架构提供超强可扩展性 BSD 协议授权,可用于商业闭源项目 下载地址:https://orchard.codeplex.com/releases/view/119931 相关博客:http://www.orchardch.com/Blog 一个基于Orchard的开源CRM --coevery

Caf.CMS是一个免费的、 开源,功能齐全的CMS

Caf.CMS(疯狂蚂蚁CMS) 是一个免费的. 开源,功能全面的CMS(内容管理系统).定位CMS也有点狭义呢,因为Caf.CMS是基于国外SmartStore.NET 开源商城源码的基础上改造而成的CMS. 定位:由于基于Smartstore.Net开源商城框架进行改造,所以整体上相对于其他几MB的CMS来说,Caf.CMS比较笨重,只适合编程人员进行模板开发及功能扩展. github:https://github.com/crazyants/Caf.CMS 功能: 1.多站点支持 支持后台

100offer举办的「寻找实干和坚持的技术力量」开源项目投票排名分析程序

由于100offer举办的「寻找实干和坚持的技术力量」开源项目投票活动没有按照票数排序的功能,所以本文写了个小程序来实现这个功能,代码如下: import org.jsoup.Jsoup; import org.jsoup.nodes.Element; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /**

微管理——给你一个技术团队,你该怎么管

微管理--给你一个技术团队,你该怎么管(最简洁.最高效的团队管理落地实践方法,IT/互联网行业15年管理实践 + 中欧商学院EMBA经历,杨老师手把手教你如何用"微管理"打造高效团队/京东:最简洁高效的IT/互联网团队管理实践方法) 杨立东 著   ISBN 978-7-121-22886-5 2014年5月出版 定价:59.00元 236页 16开 编辑推荐 1.最简洁.最高效的团队管理落地实践方法,IT/互联网团队管理的宝典,用互联网思维打造的技术管理NO.1实战手册. 2.IT/

如何编写一个企业级Hyperledger Fabric开源框架

Convector(a.k.a Convector Smart Contracts)是为企业区块链框架构建的JavaScript开发框架.它增强了开发体验,同时帮助开发人员创建更强大,更安全的智能合约系统.它通过链代码和后端一直到前端,允许开发人员以库的形式重用相同的代码库.它基于模型/控制器模式,支持Hyperledger Fabric,并沿着Fabric精心设计的模式本地运行. 这篇博客文章介绍了该项目的历史,并重点介绍了沿途开发的挑战和解决方案. 当我们开始研究Tellus时,一切都开始了