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

.NET 5 API中如何为ValidationAttribute校验结果添加自定义响应码?

解决方案

问题根因

ASP.NET Core 中带有 [ApiController] 标记的控制器默认启用了自动模型校验逻辑,该逻辑优先级高于自定义 ActionFilter,校验失败时会直接返回 400 响应,不会进入你编写的过滤器逻辑,这就是你之前代码不生效的原因。

方案1:关闭默认自动校验,复用现有逻辑

只需要在 Startup.cs 的 ConfigureServices 方法中添加如下配置,关闭默认的模型校验过滤器即可让你的自定义过滤器正常触发:

services.Configure<ApiBehaviorOptions>(options =>
{
    // 关闭默认自动模型校验响应
    options.SuppressModelStateInvalidFilter = true;
});

配置完成后你之前写的 RequestModelValidationAttribute 就可以在校验成功、失败的场景下正常执行,不需要修改原有逻辑。

方案2:自定义带错误码的校验特性+替换全局校验响应工厂(更优雅的长期方案)

该方案不需要硬编码属性名对应错误码,可直接在业务模型的校验特性上配置对应错误码,可维护性更高:

步骤1:定义带错误码的自定义校验特性

/// <summary>
/// 带业务错误码的自定义校验特性
/// </summary>
public class BusinessValidationAttribute : ValidationAttribute
{
    /// <summary>
    /// 业务错误码
    /// </summary>
    public string ErrorCode { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 这里写入你原来的自定义校验逻辑
        bool isValid = /* 你的校验规则 */;
        if (!isValid)
        {
            // 返回携带错误码和错误消息的校验结果
            return new ValidationResult($"{ErrorCode}|{ErrorMessage}");
        }
        return ValidationResult.Success;
    }
}

步骤2:替换默认的模型校验失败响应工厂

services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        var apiResponse = new ResponseModel<ResponseAPI>
        {
            ResponseMessage = "出现一个或多个校验错误。"
        };

        // 取第一个校验失败的属性返回
        var invalidModel = context.ModelState
            .FirstOrDefault(m => m.Value.ValidationState == ModelValidationState.Invalid);
        
        if (invalidModel.Value != null)
        {
            var errorMsg = invalidModel.Value.Errors.First().ErrorMessage;
            // 拆分错误码和错误消息
            var msgParts = errorMsg.Split('|', 2);
            if (msgParts.Length == 2)
            {
                apiResponse.ResponseCode = msgParts[0];
                apiResponse.Errors.Add(invalidModel.Key, new List<string> { msgParts[1] });
            }
            else
            {
                // 系统默认校验错误走默认错误码
                apiResponse.ResponseCode = "01";
                apiResponse.Errors.Add(invalidModel.Key, new List<string> { errorMsg });
            }
        }

        // 可根据需求修改HTTP状态码,比如返回200也可以
        return new BadRequestObjectResult(apiResponse);
    };
});

步骤3:业务模型中使用

直接在需要校验的属性上配置对应错误码即可:

public class 你的请求类
{
    [BusinessValidation(ErrorCode = "01", ErrorMessage = "Property1不符合要求")]
    public string Property1 { get; set; }

    [BusinessValidation(ErrorCode = "02", ErrorMessage = "Property2不符合要求")]
    public string Property2 { get; set; }

    [BusinessValidation(ErrorCode = "03", ErrorMessage = "Property3不符合要求")]
    public string Property3 { get; set; }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:15:04