.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))
{//todoforeach (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的支持,默认情况下启用。

补充

有博友提问了下图中的几个问题:

当前API版本反序列化不会将JSON字符串中的数字强制转换;但是JsonConverter转换器功能可以逐个属性有效地选择转换:

public class NumberToStringConverter : JsonConverter<int>{public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){var number = 0;if (reader.TokenType == JsonTokenType.String){if (Int32.TryParse(reader.GetString(), out number))return number;}return reader.GetInt32();}public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options){writer.WriteStringValue(value.ToString());}}class Sample{public string Date { get; set; }public int Summary { get; set; }}var json = "{\"Date\":\"2019-10-31\",\"Summary\":\"1\"}";var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true };options.Converters.Add(new NumberToStringConverter());var deserialize = JsonSerializer.Deserialize<Sample>(json, options);

当前API版本支持System.Text.Json 支持Dictionary<key,value>序列化。

Dictionary<string, object> dictionary = new Dictionary<string, object>{{"1", 2}};var serialize = JsonSerializer.Serialize(dictionary);var temjson = "{\"1\":2}";var deserializeDictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(temjson);

相关文章:

在.Net Core 3.0中尝试新的System.Text.Json API相关推荐

  1. [译]试用新的System.Text.Json API

    译注 尝试新的System.Text.Json API 对于.NET Core 3.0,我们 提供了一个名为System.Text.Json的全新命名空间 ,支持读取器/写入器,文档对象模型(DOM) ...

  2. .NET 6 新特性 System.Text.Json 中的 Writeable DOM

    .NET 6 新特性 System.Text.Json 中的 Writeable DOM 特性 Intro 在 .NET 6 Preview 4 中,微软加入了 JSON Node 的支持,我们可以动 ...

  3. Teams Bot 如何使用新的 System.Text.Json 库

    我最近把 LuckyDraw的代码升级到了 .net core 3.1,当然我也很想使用最新的微软json库,System.Text.Json这个库的性能比之前Newtonsoft.Json速度更快, ...

  4. .NET Core 3.0 中的新变化

    译者:楚人Leo 译文:http://www.cnblogs.com/leolion/p/10585834.html 原文:https://msdn.microsoft.com/en-us/magaz ...

  5. .NET Core 3.0中的新功能和增强功能

    目录 介绍 主要变化 Windows桌面支持 本机可执行文件 JSON API 更好的垃​​圾收集器 性能改进 Docker增强 ARM64支持 物联网支持 密码学 与.NET Core 2.2的AP ...

  6. .NET 6 中的七个 System.Text.Json 特性

    忽略循环引用 在 .NET 5 中,如果存在循环依赖, 那么序列化的时候会抛出异常, 而在 .NET 6 中, 你可以选择忽略它. Category dotnet = new() {Name = &q ...

  7. ASP.NET Core 3.0中使用动态控制器路由

    原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...

  8. 在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想

    源码:https://github.com/Martin1994/JsonJitSerializer NuGet:https://www.nuget.org/packages/MartinCl2.Te ...

  9. 避免在 ASP.NET Core 3.0 中为启动类注入服务

    本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostin ...

最新文章

  1. 睿云智合(Wise2C)谈论docker
  2. Android调用手机浏览器打开某网页出现异常情况
  3. MySQL5.7 Group Replication (MGR)--Mysql的组复制之多主模式
  4. [转] 前端中的MVC
  5. 【剑指Offer】60、把二叉树打印成多行
  6. [COLING18]两种成分句法分析的局部特征模型
  7. 使用 SQL Server 代理来计划 SSAS 管理任务
  8. Qt学习之路系列教程目录
  9. win10 SqlServer2008 卸载 亲测可行
  10. 2.三种前端跨域的解决方法
  11. ps如何设置裁剪后的背景颜色
  12. JSON数据乱码解决方法
  13. 【IIS】XP系统的IIS发布
  14. 快牛策略——PowerPoint 2003:红头文件的制作及标准
  15. 终于给自己买了台电脑
  16. GC详解---JVM(三)
  17. 【云服务器】免费云服务器推荐
  18. ESP8266小白之摸爬滚打经验
  19. 购买域名和虚拟空间对于建站的必要性
  20. WLAN和E-UTRAN小区重选

热门文章

  1. 【啊哈!算法】之二、插入排序
  2. html frame跳转实例,HTML frame标签怎么用?frame标签的具体使用实例
  3. scss2css vscode设置_VSCode下让CSS文件完美支持SCSS或SASS语法方法
  4. 棉花糖多少钱_如何在6.0棉花糖及更高版本中访问Android的正在运行的应用程序列表...
  5. HashMap是如何工作的
  6. WCF分布式开发常见错误(25):The certificate 'CN=WCFHTTPS' must have a private key
  7. 张萍萍 计科高职13-1 201303014010
  8. mysql数据库的备份和二进制日志恢复
  9. MDT部署中命令行脚本的使用。
  10. 数学知识在游戏中的运用