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

ASP.NET Core 3.1 Dto类属性自定义ModelBinder未触发问题咨询

问题原因与解决方案

根本原因

你的控制器Action参数标注了[FromBody],ASP.NET Core中[FromBody]默认使用JSON序列化器(System.Text.Json或Newtonsoft.Json)直接反序列化请求体,不走常规的ModelBinder执行流程:

  • 你编写的SessionIdModelBinder、MyCustomModelBinderProvider仅对路由、查询字符串、表单数据等非请求体JSON的数据源生效
  • JSON序列化器无法识别自定义SessionId类型的反序列化规则,反序列化失败后整个dto参数被判定为null,触发ASP.NET Core 3.1默认的非空参数校验,就会返回The dto field is required.报错

解决方案

方案1:继续使用[FromBody]接收JSON请求,新增JSON类型转换器

这是最推荐的方案,符合JSON请求的处理逻辑。

若使用默认System.Text.Json序列化器

  1. 实现自定义JsonConverter
public class SessionIdJsonConverter : JsonConverter<SessionId>
{
    public override SessionId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var value = reader.GetString();
        var parseResult = SessionId.Parse(value);
        if (parseResult.IsFailure)
        {
            throw new JsonException(parseResult.Errors.First().Message);
        }
        return parseResult.Data;
    }

    public override void Write(Utf8JsonWriter writer, SessionId value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}
  1. 全局注册转换器
services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new SessionIdJsonConverter());
    });

若使用Newtonsoft.Json序列化器

  1. 实现自定义JsonConverter
public class SessionIdNewtonsoftConverter : JsonConverter<SessionId>
{
    public override void WriteJson(JsonWriter writer, SessionId value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString());
    }

    public override SessionId ReadJson(JsonReader reader, Type objectType, SessionId existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var value = reader.Value?.ToString();
        var parseResult = SessionId.Parse(value);
        if (parseResult.IsFailure)
        {
            throw new JsonSerializationException(parseResult.Errors.First().Message);
        }
        return parseResult.Data;
    }
}
  1. 全局注册转换器
services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.Converters.Add(new SessionIdNewtonsoftConverter());
    });

方案2:不使用[FromBody],沿用已有的ModelBinder逻辑

如果你的请求参数不是JSON格式,直接去掉Action参数上的[FromBody]特性,或者根据数据源替换为[FromForm]/[FromQuery],已注册的MyCustomModelBinderProvider就会自动生效,Dto属性上的[ModelBinder]特性也可以省略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:09:02