Sweet Jayson





5.00/5 (2投票s)
快速、可靠、易于使用、完全符合 json.org 标准、线程安全的 C# JSON 库,适用于服务器端和桌面操作
- 从 https://nuget.net.cn/packages/Sweet.Jayson 下载库
- 从 https://github.com/ocdogan/Sweet.Jayson 下载源代码。它根据 MIT 许可。
引言
互联网上有许多 .NET JSON 库。有些声称小巧,有些声称快速。大多数情况下它们是对的,但可靠性如何呢?深入研究后,你会发现根据你的具体情况,它们会缺少一些东西,而你无法成功使用该库,或者你需要编写越来越多的扩展来处理你的特定情况。忘掉所有这些,试试 Sweet.Jayson
。
背景
它快速、可靠、易于使用、线程安全且完全符合 json.org 标准。它是从头开始设计和编码的,一直牢记这些,而不是在某个时间点才考虑。
承诺的内容?
Sweet.Jayson JSON 库支持
public class CustomBaseType
{
public string Label { get; set; }
public string Ref { get; set; }
public string SHA { get; set; }
public List<string> Items { get; set; }
}
public class CustomType
{
public string State;
public CustomBaseType Base { get; set; }
}
public static class Program
{
public static void Main(params string[] args)
{
var dto = new CustomType() {
{
State = "open"
Base = new CustomBaseType()
{
Label = "technoweenie:master",
Ref = "master",
SHA = "53397635da83a2f4b5e862b5e59cc66f6c39f9c6",
Items = new List<object> { "Dev", "Test", "Prod" }
}
};
var jsonObj =
(Dictionary<string, object>)JaysonConverter.ToJsonObject(dto);
}
}
- .NET 3.5、4.0、4.5 和 Mono
- 任何 POCO 类型序列化/反序列化
- 默认 .NET 类型 (
DateTime
,DateTimeOffset
,TimeSpan
,Guid
,ArrayList
,Hashtable,
HashSet
...) - 默认和自定义通用 .NET 类型 (
List<T>
,Dictionary<T,K>
,Stack<T>
,Queue<T>
...) - 并发集合类型 (
ConcurrentBag<T>
,ConcurrentDictionary<T,K>
,
ConcurrentStack<T>
,ConcurrentQueue<T>
) - 任何键类型非
typeof(string)
的字典类型,带有特殊的键值对 ($k
,$v
) 对象 (IDictionary<int,decimal>
,IDictionary
,Hashtable
...) DataTable
,DataSet
(以及 自定义DataSets
和DataTable 在
DataSets
中的关系)Nullable
类型 (int?
,DateTime?
...)- 接口,包括默认 .NET 接口和自定义接口 (
IList
,IList<T>
,IMyCustomInterface
...) - 数组类型 (类 和 值 类型) (
int[]
,char[]
,string[]
...) - 字节数组 (
byte[]
) 作为Base64String
- 多维数组 (
int[,]
) - 交错数组 (
int[][]
) - 混合数组 (
int[][,]
和int[,][]
) dynamic
类型struct
类型,包括序列化和反序列化- 没有默认构造函数的类型 (例如
Tuple
) - 使用 "
$type
" 表示法嵌入类型信息以进行精确类型反序列化 - 使用 "
$types
" 表示法嵌入全局类型信息以进行精确类型反序列化和紧凑输出 - 包含或排除 "
null
" 值到/从输出 (在Properties
或Lists
中分开), - 将
Guid
序列化为字节数组 (byte[]
) - 区分大小写的/不区分大小写的属性名称
{ "state": "open", "base": { "label": "technoweenie:master", "ref": "master", "sha": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
或
{ "State": "open", "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
- 启用/禁用 格式化 和 美化输出(美化打印),而不会损失性能
{"state"":"open","base"":{"label":"technoweenie:master", "ref"":"master","sha"":"53397635da83a2f4b5e862b5e59cc66f6c39f9c6"}}
或
{ "state": "open", "base": { "label": "technoweenie:master", "ref": "master", "sha": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
- 使用
System.Runtime.Serialization.SerializationBinder
更改反序列化中的类型, - 通过
JaysonTypeOverride
将Property
和Field
名称更改为任何值,而无需使用自定义Attribute
类var dto1 = TestClasses.GetTypedContainerDto(); JaysonSerializationSettings jaysonSerializationSettings = JaysonSerializationSettings.DefaultClone(); jaysonSerializationSettings.TypeNames = JaysonTypeNameSerialization.All; jaysonSerializationSettings. AddTypeOverride( new JaysonTypeOverride<TextElementDto>(). IgnoreMember("ElementType"). SetMemberAlias("ElementId", "id")); JaysonDeserializationSettings jaysonDeserializationSettings = JaysonDeserializationSettings.DefaultClone(); jaysonDeserializationSettings. AddTypeOverride( new JaysonTypeOverride<TextElementDto, TextElementDto2>()). AddTypeOverride(new JaysonTypeOverride<TextElementDto2>(). SetMemberAlias("ElementId", "id"). IgnoreMember("ElementType")); string json = JaysonConverter.ToJsonString(dto1, jaysonSerializationSettings); var dto2 = JaysonConverter.ToObject<TypedContainerDto>(json, jaysonDeserializationSettings);
- 使用
JaysonTypeOverride
更改序列化/反序列化中的类型 - 通过
JaysonTypeOverride
忽略Field
和Properties
- 包含或排除只读成员 (
Field
&Properties
) 到/从序列化 - 匿名类型 序列化/反序列化(只有当类型已存在于当前进程中时,反序列化才可能)
- 自定义
Number
(byte
,short
,int
,long
,float
,double
,decimal
,sbyte
,ushort
,uint
,ulong
),
DateTime
,DateTimeOffset
和TimeSpan
在序列化中的格式 - 通过
JaysonDateFormatType
进行各种DateTime
序列化/反序列化格式:Iso8601Local date: "1983-10-25T16:00:30.345+0300" UTC date: "1983-10-25T13:00:30.345Z"
Microsoft
Local date: "/Date(1224043200000+0300)/" UTC date: "/Date(1224043200000)/"
JScript
Local date: new Date(1224043200000+0300) UTC date: new Date(1224043200000)
UnixEpoch
Any long number: 1224043200000
CustomDate
Any date custom date format defined in serialization settings
CustomUnixEpoch
Any custom long number format defined in serialization settings
-
将
Decimal
值转换为Double
或将其保留为Decimal
形式 -
启用/禁用
AnonymousTypes
,DynamicObject
和ExpandoObject 类型
- 启用/禁用 Unicode 字符转义
\u0357
- 按降序 对
Field
和Property
名称进行排序 - 忽略
Circular References
或在遇到 Circular Reference 时抛出异常 - 使用
Enum
类型名称或数字Enum
值 - 反序列化中的最大对象深度
- 使用默认类型(如
Dictionary<string,object>
或ExpandoObject
)进行操作的选项,
List<object>
,ArrayList
或Array
而不是将对象转换为自定义 .NET 类型- 解析 JSON 数组
[]
在List<object>
,ArrayList
或Array
之间转换的选项 - 将 JSON 对象
{}
解析为Dictionary<string, object>
或ExpandoObject
的选项
{ "State": "open", "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6", "Items": [ "Dev", "Test", "Prod" ] } }
将被解析为
new Dictionary<string, object> { { "State": "open" }, { "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6", "Items": new List<object> { "Dev", "Test", "Prod" } } } };
- 解析 JSON 数组
- 使用
JaysonObjectActivator
在转换过程外创建自定义对象 - 使用
JaysonConverter.ToJsonObject
函数将任何 .NET 对象转换为Dictionary<string,object>
和List<object>
- 使用
$id
和$ref
标签进行对象引用,{ "$type": "ObjectToDict.A, ObjectToDict", "$id": 1, "O2": { "1": { "$type": "System.Decimal, mscorlib", "$value": 2 }, "$id": 2, "a": "b", "true": false, "#self": { "$ref": 2 }, "#list": { "$type": "System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib", "$id": 3, "$values": [ { "$ref": 2 } ] } }, "O1": true, "E1": "EnumB, EnumC", "D2": 23456.78901, "L2": { "$id": 4, "$values": [ 1, null, 2, null ] }, "L1": { "$type": "System.Int64, mscorlib", "$value": 12345678909876544 }, "D4": { "$ref": 2 }, "D1": { "$type": "System.Decimal, mscorlib", "$value": 12345.6789 }, "I1": 123456789 }
-
启用或禁用
Dictionary<?,object>
的KV
模式{ "$type": "Sweet.Jayson.Tests.A, Sweet.Jayson.Tests", "D3": { "$type": "System.Collections.Generic.Dictionary`2 [[System.Object, mscorlib],[System.Object, mscorlib]], mscorlib", "1": { "$type": "System.Decimal, mscorlib", "$value": 2 }, "a": "b", "True": false } }
或
{ "$type": "Sweet.Jayson.Tests.A, Sweet.Jayson.Tests", "D3": { "$type": "System.Collections.Generic.Dictionary`2 [[System.Object, mscorlib],[System.Object, mscorlib]], mscorlib", "$kv": [ { "$k": 1, "$v": { "$type": "System.Decimal, mscorlib", "$value": 2 } }, { "$k": "a", "$v": "b" }, { "$k": true, "$v": false } ] } }
关注点
JSON 是一种用于传输对象状态的简化表示法。它简单易用,适用于 JScript、Pyton、Ruby 或任何其他动态语言,但当在静态编译语言中使用时,将其映射和绑定到类会非常痛苦。
不要认为 .NET 库为您提供了市面上最好的选择。大多数情况下,它们旨在支持通用场景并且编码不佳。.NET 是一个很棒的框架,但在每个特定场景下,它都会显得不足。
我的观点是,当您需要性能和稳定性时,您需要尝试自己编写,或者在测试时尝试第三方库。同时,不要认为每个著名的第三方库都很棒。大多数情况下,它们出名只是偶然,或者因为它们是该领域的第一个。因此,您也需要仔细测试它们,并接受它们在很多情况下是成功的,但并非所有情况都如此。但是,如果您也处于这种情况并打算编写自己的库,请记住要为不眠不休的日子做好准备。
该库是在测试了许多第三方库和 .NET 自带的 JSON 序列化和反序列化库后开始的。当它们失败或需要付出太多努力才能满足大多数特定需求时,我感到厌倦,需要编写一个新的库,这就是这个新面孔,并希望分享它,让其他人不必经历同样的痛苦。
如果您在库方面需要任何帮助,请随时与我联系。
历史
v1.0.0.0
- 2015 年 5 月 3 日,初始发布
v1.0.0.1
- 2015 年 6 月 6 日,增加了对特殊类型;Stack、Queue 和 Concurrent 列表的支持
v1.0.0.2
- 2015 年 6 月 6 日,对列表处理进行了小幅修复,当最后一个元素是
null
或布尔值时
v1.0.0.3
- 2015 年 6 月 8 日,GUID 序列化性能优化
v1.0.0.4
2015 年 6 月 9 日
- 进行了一些重构
- 封锁了一些类
- 实现了错误消息类
- 为 JaysonError 文件添加了许可证标题
v1.0.0.5
2015 年 6 月 9 日
- 长数字序列化修复
AsciiToLower
&AsciiToUpper
修复
v1.0.0.6
2015 年 6 月 10 日
- 添加了新测试
IDictionary<object, object>
键转换修复ConvertToPrimitive
为enum
s 修复
v1.0.0.7
2015 年 6 月 11 日
- 性能改进
- 实现了
JaysonOrderedDictionary
以用于成员名称 - 详细的测试用例
v1.0.0.8
2015 年 6 月 17 日
- 对象引用支持
- 性能优化
- 用于启用/禁用
Dictionary<?,object>
的KV
模式的设置 - 详细的测试用例
v1.0.0.9
2015 年 7 月 14 日
System.Runtime.Serialization.ISerializable
接口支持System.Type System.Type
序列化支持System.Reflection.ConstructorInfo, System.Reflection.MethodInfo
,System.Reflection.PropertyInfo
和System.Reflection.FieldInfo
序列化支持System.Exception
序列化支持- 修复了 .Net System.Type.GetType,其工作方式与 Mono 版本不同
- 详细的测试用例