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

ASP.NET Core 2.0校验:语法问题与校验问题的区分处理

区分ModelState错误类型,返回400或422状态码

当然可以区分!在ASP.NET Core 2.0中,我们可以通过ModelState里错误的特征来判断是JSON语法错误还是数据校验错误,从而返回对应的HTTP状态码。下面给你具体的实现方案:

一、在控制器内直接判断

你可以在CreateArticle方法里检查ModelState的错误细节:

[HttpPost]
public async Task<IActionResult> CreateArticle([FromBody] CreateArticleInput input)
{
    if (!ModelState.IsValid)
    {
        // 判断是否是JSON语法错误
        bool isJsonSyntaxError = false;

        // 检查是否存在根路径($)的解析错误,这是JSON格式错误的典型标志
        if (ModelState.ContainsKey("$"))
        {
            isJsonSyntaxError = true;
        }
        // 或者检查错误是否来自JSON解析异常(根据你使用的序列化器调整)
        else
        {
            // ASP.NET Core 2.0默认使用Newtonsoft.Json,用这个判断
            isJsonSyntaxError = ModelState.Values
                .Any(v => v.Errors.Any(e => e.Exception is Newtonsoft.Json.JsonException));
            
            // 如果后续切换到System.Text.Json,换成下面的判断
            // isJsonSyntaxError = ModelState.Values
            //     .Any(v => v.Errors.Any(e => e.Exception is System.Text.Json.JsonException));
        }

        if (isJsonSyntaxError)
        {
            // 返回400 Bad Request,提示JSON格式错误
            return BadRequest(new { Message = "Invalid JSON format in request body" });
        }
        else
        {
            // 返回422 Unprocessable Entity,附带具体的校验错误
            return UnprocessableEntity(ModelState);
        }
    }

    // 后续正常业务逻辑
    return Ok();
}

二、全局过滤器(推荐)

如果你的项目里多个控制器都需要这个逻辑,写个全局过滤器更高效,不用重复代码:

1. 创建自定义过滤器

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json; // 对应ASP.NET Core 2.0默认的序列化器

public class ModelStateValidationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            bool isJsonError = context.ModelState.ContainsKey("$") || 
                               context.ModelState.Values.Any(v => 
                                   v.Errors.Any(e => e.Exception is JsonException));

            if (isJsonError)
            {
                context.Result = new BadRequestObjectResult(new 
                { 
                    Message = "Request body contains invalid JSON" 
                });
            }
            else
            {
                context.Result = new UnprocessableEntityObjectResult(context.ModelState);
            }
        }
    }
}

2. 注册过滤器

在Startup.cs的ConfigureServices方法里添加:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        // 添加全局过滤器
        options.Filters.Add<ModelStateValidationFilter>();
    });
}

这样所有控制器的ModelState校验都会自动区分错误类型,返回对应的状态码,不用再在每个Action里写判断逻辑。

原理说明

  • 当JSON格式错误时,ASP.NET Core的Body解析器会在ModelState中添加一个键为$的错误,或者抛出JsonException(取决于序列化器),这是我们判断的核心依据。
  • 而Required、StringLength这类校验错误,是模型绑定成功后,由数据注解验证产生的,不会有根路径的$键,也不会有JSON解析异常。

这样处理完全符合HTTP状态码的语义:400表示请求本身格式错误(无法解析),422表示请求格式正确但内容不符合校验规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:37:04