How to discern between model binding errors and model validation errors?

血红的双手。 提交于 2019-12-01 09:31:45

Haven't checked option #1 yet, but:

  • ModelState.ValidationState has 4 possible values (Unvalidated, Invalid, Valid, Skipped) where in case of model binding errors I do get Unvalidated as a value
  • Also would consider using ApiBehaviorOptions (see sample here) to automatically return a new BadRequestObjectResult(actionContext.ModelState) - since in case of binding error with a NULL bound value there's nothing to do and in case of validation errors we probably can't do anything either.

Quick notes for the ApiBehaviorOptions:

  • must use ApiController attribute (which requires also routing attribute on the controller level also and does alter the way binding works)
  • the default behaviour with ApiController attribute will return a BadRequestObjectResult(actionContext.ModelState) without any extra code and configuration
  • if you decide to roll your own ApiBehaviorOptions - you must initialize it after service.AddMvc or need to use: services.PostConfigure(o => {}) which has similar effect
  • ApiBehaviorOptions SuppressModelStateInvalidFilter has to be false for the InvalidModelStateResponseFactory to work

So in some cases a custom filter is a better solution (less changes).

Add attribute below in your project

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))
            });
    }
}

Change your api like this

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

id contains a non-digit => 400

model does not pass annotation validation inside => 400

if you want to reject unacceptable values in model with 422 code, implement in your controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!