You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 9 HybridCache+Redis环境下NodaTime Instant序列化问题求助

.NET 9 HybridCache 搭配 DragonFly 时 NodaTime Instant 序列化问题的解决方案

问题场景

在.NET 9中使用HybridCache配合DragonFly(基于Redis)作为分布式缓存,基础配置如下,可正常运行:

builder.Services.AddStackExchangeRedisCache(options => options.Configuration = redisConnectionString);
// ...
builder.Services.AddHybridCache(options => options.ReportTagMetrics = true);

但当缓存对象包含NodaTime的Instant类型属性时,该属性在缓存存储中会变为空值。通常在MassTransit+RabbitMQ场景中,通过配置JSON序列化器支持NodaTime即可解决:

x.UsingRabbitMq((context, cfg) =>
{
    // ...
    cfg.ConfigureJsonSerializerOptions(j => j.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb));
    // ...
});

尝试过的无效方案

  • 实现IHybridCacheSerializer<Instant>并注册到DI容器,未被框架调用
  • 使用.AddSerializer方法(本质是AddSingleton的包装)注册自定义序列化器,无效果
  • 自定义实现IHybridCacheSerializerFactory,但该服务从未被框架解析
  • 临时方案:通过反射将NodaTime序列化器添加到默认转换器列表,属于非常规hack手段

可行解决方案

根据Mark Gravel的指导,重新实现默认的IHybridCacheSerializerFactory,并使用独立配置的JsonSerializerOptions实例(已配置NodaTime支持),这是完全合规的解决方案。

具体实现代码

  1. 自定义序列化器工厂:
public class NodaTimeHybridCacheSerializerFactory : IHybridCacheSerializerFactory
{
    private readonly JsonSerializerOptions _jsonOptions;

    public NodaTimeHybridCacheSerializerFactory()
    {
        _jsonOptions = new JsonSerializerOptions();
        _jsonOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
        // 可添加其他默认序列化配置,比如忽略null值等
    }

    public IHybridCacheSerializer CreateSerializer(Type type)
    {
        return new JsonHybridCacheSerializer(type, _jsonOptions);
    }
}
  1. 替换默认的工厂注册:
builder.Services.AddHybridCache(options => options.ReportTagMetrics = true);
// 替换默认的序列化器工厂
builder.Services.AddSingleton<IHybridCacheSerializerFactory, NodaTimeHybridCacheSerializerFactory>();

这样配置后,HybridCache在序列化包含Instant属性的对象时,会正确使用带NodaTime支持的JSON序列化器,解决属性为空的问题。


内容的提问来源于stack exchange,提问作者ZorgoZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:19:54