DateOnly和TimeOnly类型居然不能序列化!!! .Net 6下实现自定义JSON序列化

前言

.Net 6引入了DateOnly和TimeOnly结构,可以存储日期和时间。

但在实际使用时,发现一个很尴尬的问题,DateOnly和TimeOnly居然不能被序列化:

var builder = WebApplication.CreateBuilder(args);
 
var app = builder.Build();
 
app.MapGet("/timeonly", () => new TimeOnly(1,0,0) );
app.MapGet("/dateonly", () => new DateOnly(2021,12,01) );

app.Run();

36ac059eb1fe8372afdc59039f022b73.png

那要这两类型还有何用!

解决方案

自定义转换器

为了解决这个问题,我们需要创建两个自定义转换器来处理这些类型,以TimeOnly为例:

public class TimeOnlyConverter : JsonConverter<TimeOnly>
{
    public override TimeOnly Read(ref Utf8JsonReader reader,
                            Type typeToConvert, JsonSerializerOptions options)
    {
        var value = reader.GetString();
        return TimeOnly.Parse(value!);
    }

    public override void Write(Utf8JsonWriter writer, TimeOnly value,
                                        JsonSerializerOptions options)
        => writer.WriteStringValue(value.ToString("HH:mm:ss"));
}

继承JsonConverter类,并实现ReadWrite方法。

配置

现在,我们需要将自定义转换器配置到序列化选项上。

在.NET 6之前,是修改Startup.cs文件:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddJsonOptions(options =>
            options.JsonSerializerOptions.Converters.Add(new TimeOnlyConverter()));
}

但是在.NET 6中已经没有Startup.cs文件,也不用Controller了。

4986e057c3cb6fbecee2cbf574aae89a.png

查看AddJsonOptions方法的源码,发现它实际上调用的是builder.Services.Configure方法:

public static IMvcCoreBuilder AddJsonOptions(
        this IMvcCoreBuilder builder,
        Action<JsonOptions> configure)
{
    if (builder == null)
    {
        throw new ArgumentNullException(nameof(builder));
    }

    if (configure == null)
    {
        throw new ArgumentNullException(nameof(configure));
    }

    builder.Services.Configure(configure);
    return builder;
}

于是,我们同样使用builder.Services.Configure方法进行配置:

using Microsoft.AspNetCore.Http.Json;

var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<JsonOptions>(options =>
    options.SerializerOptions.Converters.Add(new TimeOnlyConverter()));

运行结果正确:

0d508e94b0664a3284316dcc6808f3f2.png

结论

不清楚官方为什么默认不支持DateOnly和TimeOnly类型序列化。

如果你碰到类似本文这种情况,可以使用自定义转换器解决。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值