asp.net core custom model validation output

Starting at asp.net core 2.something, a unified model binding err is return, when input does not bind to an expected model. Api returns 400 with a msg similar to:

{
    "someProperty": [
        "Some error."
    ]
}

There are scenarios however when one may want to return a customised error msg that is used across an application. In order to do this, the following should be done:

Disable the default model validation:

public void ConfigureServices(IServiceCollection services)
{
      //...

      //this should disable the default model validation, so custom attribute can be used instead
      services.Configure<ApiBehaviorOptions>(opts =>
      {
          opts.SuppressModelStateInvalidFilter = true;
      });

      //...
}


Create a custom action filter:

public class ValidateModelFilterAttribute: ActionFilterAttribute
{
    /// 
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            var errs = context.ModelState.Keys.Select(
                key => context.ModelState[key].Errors.Select(e =>
                    $"{key}: {(!string.IsNullOrWhiteSpace(e.ErrorMessage) ? e.ErrorMessage : e.Exception.Message)}")
            ).SelectMany(x => x).ToArray();

            context.Result = new ObjectResult(new {Errors: errs})
            {
                StatusCode = (int) HttpStatusCode.BadRequest
            };
        }
    }
}


Decorate controller or method with the custom filter or set it to be used globally.


More info here: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2

blog comments powered by Disqus