如何区分模型绑定错误和模型验证错误?

Alb*_*reo 5 c# model-binding model-validation asp.net-core-mvc

我正在使用 ASP.NET Core MVC 2.0 实现一个 REST API 项目,如果模型绑定失败(因为请求语法错误),我想返回 400 状态代码,如果模型验证失败,我想返回 422 状态代码(因为该请求在语法上是正确的,但包含不可接受的值)。

例如,给定一个动作,如

[HttpPut("{id}")]
public async Task<IActionResult> UpdateAsync(
    [FromRoute] int id,
    [FromBody] ThingModel model)
Run Code Online (Sandbox Code Playgroud)

id路由中的参数包含非数字字符或请求中未指定正文时,我想返回 400 状态代码,当属性ThingModel包含无效值时返回 422 状态代码。

从我所看到的情况来看,IValueProviderIModelBinder实现都ModelStateDictionary像验证器一样将它们的错误添加到请求中,并且无法在绑定和验证之间注入代码。

我怎样才能实现这样的行为?

Hun*_*ach 0

在您的项目中添加以下属性

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        base.OnActionExecuting(context);

        if (!context.ModelState.IsValid)
            context.Result = new BadRequestObjectResult(new
            {
                message = context.ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage))
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样改变你的api

[HttpPut("{id}")]
[ValidateModel]
public async Task<IActionResult> UpdateAsync(
    [FromRoute] int id,
    [FromBody] ThingModel model)
Run Code Online (Sandbox Code Playgroud)

id包含非数字 => 400

model未通过内部注释验证 => 400

如果您想使用422代码拒绝模型中不可接受的值,请在控制器中实现