在.Net Core 3.0中尝试新的System.Text.Json API
.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序。在此博客文章中,我将介绍它如何工作以及如何使用。
官方文档
获取JSON库
- 如果以.NET Core为目标,请安装.NET Core 3.0及以上版本,该版本提供了新的JSON库和ASP.NET Core集成。
- 如果以.NET Standard或.NET Framework为目标。安装System.Text.Json NuGet软件包(确保安装.NET Framework4.6.0或更高版本)。为了与ASP.NET Core集成,必须以.NET Core 3.0为目标。
NET Core 3.0中JSON特性
新的JSON API通过使用Span进行性能优化,并且可以直接处理UTF-8,而无需转码为UTF-16 string 实例。这两个方面对于ASP.NET Core都是至关重要的,在ASP.NET Core中,吞吐量是关键要求。使用System.Text.Json,可以将速度提高大约1.3倍至5倍。
使用System.Text.Json
using System.Text.Json;
using System.Text.Json.Serialization;
使用序列化器Serializer
- 学习.Net Core最好的方式是查看源码,下面是JsonSerializer Serialize的部分源码:
namespace System.Text.Json
{
public static partial class JsonSerializer
{
/// <summary>
/// Convert the provided value into a <see cref="System.String"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> representation of the value.</returns>
/// <param name="value">The value to convert.</param>
/// <param name="options">Options to control the conversion behavior.</param>
/// <remarks>Using a <see cref="System.String"/> is not as efficient as using UTF-8
/// encoding since the implementation internally uses UTF-8. See also <see cref="SerializeToUtf8Bytes"/>
/// and <see cref="SerializeAsync"/>.
/// </remarks>
public static string Serialize<TValue>(TValue value, JsonSerializerOptions options = null)
{
return ToStringInternal(value, typeof(TValue), options);
}
/// <summary>
/// Convert the provided value into a <see cref="System.String"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> representation of the value.</returns>
/// <param name="value">The value to convert.</param>
/// <param name="inputType">The type of the <paramref name="value"/> to convert.</param>
/// <param name="options">Options to control the conversion behavior.</param>
/// <remarks>Using a <see cref="System.String"/> is not as efficient as using UTF-8
/// encoding since the implementation internally uses UTF-8. See also <see cref="SerializeToUtf8Bytes"/>
/// and <see cref="SerializeAsync"/>.
/// </remarks>
public static string Serialize(object value, Type inputType, JsonSerializerOptions options = null)
{
VerifyValueAndType(value, inputType);
return ToStringInternal(value, inputType, options);
}
private static string ToStringInternal(object value, Type inputType, JsonSerializerOptions options)
{
return WriteCoreString(value, inputType, options);
}
}
}
可以看到序列化最终调用的是ToStringInternal这个方法。
- 示例
class Sample
{
public DateTimeOffset Date { get; set; }
public string Summary { get; set; }
}
string Serialize(Sample value)
{
return JsonSerializer.Serialize<Sample>(value);
}
//obj
string SerializeObj(object value)
{
return JsonSerializer.Serialize(value);
}
JsonSerializerOptions用于在序列化时设置配置, 例如处理注释,null处理,尾随逗号和命名策略。
public static string ToJson(this object obj)
{
var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true, AllowTrailingCommas = true };
return JsonSerializer.Serialize(obj, options);
}
使用反序列化器Deserialize
Sample Deserialize(string json)
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true
};
return JsonSerializer.Deserialize<Sample>(json, options);
}
自定义属性来控制序列化行为
可以使用自定义属性来控制序列化行为,例如,忽略属性或者指定属性的名称:
class Sample
{
//忽略
[JsonIgnore]
public DateTimeOffset Date { get; set; }
//指定名称
[JsonPropertyName("test")]
public string Summary { get; set; }
}
使用DOM
有时,不想反序列化JSON但仍然希望对其内容进行结构化访问,这时可以使用JsonDocument
var options = new JsonDocumentOptions
{
AllowTrailingCommas = true
};
using (JsonDocument document = JsonDocument.Parse(json, options))
{
//todo
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
//todo
}
}
使用Utf8JsonWriter
var options = new JsonWriterOptions
{
Indented = true
};
using (var stream = new MemoryStream())
{
using (var writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartObject();
writer.WriteString("date", DateTimeOffset.UtcNow);
writer.WriteEndObject();
}
string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
}
使用Utf8JsonReader
byte[] data = Encoding.UTF8.GetBytes(json);
Utf8JsonReader reader = new Utf8JsonReader(data, isFinalBlock: true, state: default);
while (reader.Read())
{
Console.Write(reader.TokenType);
switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
case JsonTokenType.String:
{
string text = reader.GetString();
Console.Write(" ");
Console.Write(text);
break;
}
case JsonTokenType.Number:
{
int value = reader.GetInt32();
Console.Write(" ");
Console.Write(value);
break;
}
}
Console.WriteLine();
}
System.Text.Json中的DateTime和DateTimeOffset支持
The System.Text.Json library parses and writes DateTime and DateTimeOffset values according to the ISO 8601:-2019 extended profile. Converters provide custom support for serializing and deserializing with JsonSerializer. Custom support can also be implemented when using Utf8JsonReader and Utf8JsonWriter.
具体请参考官方文档。
示例:
public class DateTimeConverterUsingDateTimeParse : JsonConverter<DateTime>
{
/// <summary>
/// 日期格式
/// </summary>
public string dateTimeFormat { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="dateTimeFormat"></param>
public DateTimeConverterUsingDateTimeParse(string dateTimeFormat)
{
this.dateTimeFormat = dateTimeFormat;
}
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
return DateTime.Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(dateTimeFormat));
}
}
public static class JsonHelper
{
/// <summary>Converts to json.</summary>
/// <param name="obj">The object.</param>
/// <param name="dateTimeFormat">The date time format.</param>
/// <returns>System.String.</returns>
public static string ToJson(this object obj, string dateTimeFormat = "yyyy-MM-dd")
{
var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true };
options.Converters.Add(new DateTimeConverterUsingDateTimeParse(dateTimeFormat));
return JsonSerializer.Serialize(obj, options);
}
}
总结
- 在.NET Core 3.0中,System.Text.Json API提供对JSON的内置支持,包括reader/writer,只读DOM和序列化器/反序列化器。
- 主要目标是实现高性能和低内存分配。
- ASP.NET Core 3.0包括对System.Text.Json的支持,默认情况下启用。
原文地址:https://www.cnblogs.com/muran/p/11770629.html
- ASP.net实现无扩展名的URL重写。简单、方便、无需ISAPI。
- 通过自定义ServiceHost实现对WCF的扩展[实例篇]
- 通过自定义ServiceHost实现对WCF的扩展[原理篇]
- python使用rsa库做公钥解密(网上别处找不到)
- 通过“四大行为”对WCF的扩展[原理篇]
- WCF客户端运行时架构体系详解[下篇]
- WCF客户端运行时架构体系详解[上篇]
- WCF服务端运行时架构体系详解[续篇]
- [WCF-Discovery] 实例演示:如何利用服务发现机制实现服务的“动态”调用?
- [WCF-Discovery]服务如何能被”发现”
- 我的数据访问函数库的源代码(一)—— 共用部分
- 《WCF服务编程》关于“队列服务”一个值得商榷的地方
- 我的数据访问函数库的源代码(二)—— SQL语句部分
- 来源于WCF的设计模式:可扩展对象模式[上篇]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 简单的场景分析LinearLayout 源码
- 避免栽坑之掌握Jenkins工作原理
- 如何检测JavaScript中的死循环?
- vue插槽2.6.0+
- 聊聊claudb的transaction command
- Lombok 的作者,成功讨伐 IntelliJ IDEA!
- springboot2之优雅处理返回值
- 通过NVM管理Node.js多版本
- 探究 Android 签名机制和原理
- “有迹可循”的灰盒测试分析
- 想用 Gitee 做图床工具,失败了~~
- Nginx系列:配置跳转的常用方式
- Python骚操作:一行代码实现探索性数据分析
- 吊打 Tomcat ,Undertow 性能很炸!!
- 关于在android平台使用nanohttpd实现的http服务在WIFI环境下响应明显太慢的问题