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

Utf8Json自定义Int64StringConversionFormatter未被调用问题排查

排查与解决步骤

我之前也碰到过类似的问题,结合Utf8Json在AspNetCore WebApi中的工作机制,给你梳理几个最可能的原因和解决办法:

1. 确认自定义Resolver是否关联到AspNetCore的格式化器

你虽然注册了CompositeResolver并设为默认,但AspNetCore的Utf8JsonInputFormatter和Utf8JsonOutputFormatter并不会自动绑定全局默认Resolver——必须在配置这两个格式化器时,显式传入自定义Resolver实例,否则它们会默认使用StandardResolver.Default,自然不会触发你的自定义实现。

正确的配置示例:

services.AddControllers(options =>
{
    // 先移除默认的System.Text.Json格式化器(避免冲突)
    options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
    options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();

    // 创建自定义CompositeResolver
    var customResolver = CompositeResolver.Create(
        new IJsonFormatter[] { new Int64StringConversionFormatter() },
        new IJsonResolver[] { StandardResolver.Default });

    // 添加Utf8Json格式化器并传入自定义Resolver
    options.InputFormatters.Add(new Utf8JsonInputFormatter(
        options, customResolver, ArrayPool<byte>.Shared, new JsonSerializerOptions()));
    options.OutputFormatters.Add(new Utf8JsonOutputFormatter(
        customResolver, ArrayPool<byte>.Shared, new JsonSerializerOptions()));
});

2. 检查CompositeResolver的组合顺序

Utf8Json的Resolver是按顺序匹配格式化器的,如果把自定义格式化器放在默认Resolver之后,内置的long类型格式化器会先被匹配到,你的自定义实现就会被忽略。

正确的组合逻辑是:自定义格式化器优先级更高,其余类型 fallback 到默认Resolver:

var customResolver = CompositeResolver.Create(
    // 自定义格式化器放在最前面
    new IJsonFormatter[] { new Int64StringConversionFormatter() },
    // 其他类型用默认Resolver处理
    new IJsonResolver[] { StandardResolver.Default });

3. 确认是否覆盖了Nullable类型

如果你的API模型里用的是long?(可空长整型),但自定义格式化器只实现了IJsonFormatter<long>,那可空类型会匹配不到你的逻辑,需要额外实现IJsonFormatter<long?>:

public class NullableInt64StringConversionFormatter : IJsonFormatter<long?>
{
    private readonly Int64StringConversionFormatter _innerFormatter = new Int64StringConversionFormatter();

    public long? Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        if (reader.ReadIsNull()) return null;
        return _innerFormatter.Deserialize(ref reader, formatterResolver);
    }

    public void Serialize(ref JsonWriter writer, long? value, IJsonFormatterResolver formatterResolver)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }
        _innerFormatter.Serialize(ref writer, value.Value, formatterResolver);
    }
}

然后把这个新增的格式化器也加入CompositeResolver的数组中:

new IJsonFormatter[] { new Int64StringConversionFormatter(), new NullableInt64StringConversionFormatter() }

4. 验证AspNetCore确实使用了Utf8Json格式化器

有时候可能因为配置顺序问题,默认的System.Text.Json格式化器没有被完全移除,导致请求实际用的不是Utf8Json。你可以:

  • 在请求头中指定Accept: application/json
  • 调试时查看当前请求对应的格式化器类型,确认是Utf8JsonInputFormatter/Utf8JsonOutputFormatter在处理

5. 检查自定义格式化器的实现逻辑

确保你的Int64StringConversionFormatter方法签名和逻辑正确,比如:

public class Int64StringConversionFormatter : IJsonFormatter<long>
{
    public long Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        // 兼容字符串和数字类型的反序列化逻辑
        if (reader.TokenType == JsonTokenType.String)
        {
            var strValue = reader.ReadString();
            return long.Parse(strValue);
        }
        return reader.ReadInt64();
    }

    public void Serialize(ref JsonWriter writer, long value, IJsonFormatterResolver formatterResolver)
    {
        // 序列化为字符串
        writer.WriteString(value.ToString());
    }
}

可以给方法加断点或日志,确认是否真的没被调用——如果是逻辑报错导致的“看似没触发”,也能快速定位问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:49:09