Skip to content

Fast.Serialization.System.Text.Json

逐成员 API、参数与返回参考

版本 3.5.20;目标 net8.0net9.0net10.0。使用 System.Text.Json,为 MVC 与工具扩展提供共同的 JSON 约定。命名空间 Fast.Serialization

bash
dotnet add package Fast.Serialization.System.Text.Json

注册与选项作用域

AddSerialization(this IServiceCollection services, Action<Microsoft.AspNetCore.Mvc.JsonOptions> configureOptions = null) 返回服务集合。

以下为消费端 Program.cs,使用 Microsoft.NET.Sdk.Web,目标选择本页列出的 .NET 8、9 或 10,并安装上方指定包。app.Run() 表示正常宿主启动;本次文档维护不会执行它。

csharp
using Fast.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSerialization();
builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();

当前实现先创建独立 JsonOptions,应用默认设置与传入回调,并保存到 JsonContext.SerializerOptions;向 MVC 的 services.Configure 只注册默认设置。因此,自定义回调影响静态工具选项,不自动同步到 MVC。需要 MVC 自定义行为时,另外在 AddControllers().AddJsonOptions(...) 中配置相同策略。Minimal API 的 HTTP JSON 选项也不是此处 MVC JsonOptions 的同一个类型。

默认 JSON 协议

项目行为
DateTime / DateTimeOffset默认格式 yyyy-MM-dd HH:mm:ss;该格式不保留偏移文本,不宣称自动时区往返
long / long?输出 JSON 字符串,避免 JavaScript 数值精度丢失;读取支持数字与字符串
int、decimal、double 及可空类型注册对应内部转换器
枚举注册普通与可空枚举转换工厂,接受名称与数值输入
引用循环ReferenceHandler.IgnoreCycles,不等于保留对象引用关系
数字输入AllowReadingFromString
宽松输入允许尾随逗号、跳过注释、属性名不区分大小写
输出编码UnsafeRelaxedJsonEscaping;JSON 放入 HTML 时仍需按 HTML 上下文转义
Exception使用专用转换器,避免直接序列化反射成员和循环图

工具与转换器

JsonContext.SerializerOptions 公开读取,内部设置。以下扩展使用该上下文:

入口参数、返回与边界
string.ToObject<T>() / string.ToObject(Type)先移除文本中的 &nbsp;,再反序列化;输入 null 抛参数异常,非法 JSON/类型转换异常继续传播
object.ToJsonString()返回 JSON 字符串
IDictionary<string, object>.ToObject<T/Type>()经 JSON 中间表示转换,不是直接成员赋值
DeepCopy<T>(T source)null 返回 default;其余经序列化/反序列化,只保留可序列化数据
DateJsonConverter / NullableDateJsonConverter日期转换,默认 yyyy-MM-dd,可指定 format
TimeJsonConverter / NullableTimeJsonConverter时间显示转换
DataMaskingConverter(DataMaskingTypeEnum)字符串脱敏转换;包含姓名、账号、手机号、证件、邮箱、银行卡、地址、车牌、IP 等模式

不要同时引用两套 Fast.Serialization 实现来假定它们可自动切换:两个包有同名空间和同名公开类型,应用应明确选择。

对象、JSON 与字典之间的转换

在上方宿主注册完成后,业务服务可以调用这些公开扩展。以下类可直接加入同一个项目,不需要访问外部服务。

csharp
using Fast.Serialization;

public sealed class OrderSnapshot
{
    public long Id { get; set; }
    public string Title { get; set; } = "";
}

public sealed class SnapshotCodec
{
    public string Serialize(OrderSnapshot value) => value.ToJsonString();
    public OrderSnapshot Deserialize(string json) => json.ToObject<OrderSnapshot>();
    public OrderSnapshot Copy(OrderSnapshot value) => value.DeepCopy();

    public OrderSnapshot FromFields(IDictionary<string, object> fields) =>
        fields.ToObject<OrderSnapshot>();
}

long 按本包配置输出字符串;消费者不要强行当作 JavaScript number。ToObject 的 null 输入抛参数异常,格式错误或不能转换的字段由 System.Text.Json 抛出异常;JSON 字面量 null 可能返回空对象引用,尽管当前返回声明没有 nullable 标注。DeepCopy 通过一次序列化与反序列化实现,只保留可序列化内容。字典转换也经过 JSON,因此不是逐字段直接赋值,也不是无损的任意 CLR 类型转换。

来源与验证

依据 选项注册转换扩展。本轮未编译新增片段或运行序列化往返用例。

Decimal 数值精度

默认 decimal / decimal? 输出直接保留 decimal 值,不再经过 double 中转。只有显式指定小数位数时才执行现有 Math.Round 规则;可空值仍保持 null。JSON 数值在 JavaScript number 中是否能精确表达是另一层合同,高精度消费者应使用合适的数值表示。