ASP.NET Web API 2 - ModelState.IsValid true with Null Model

September 8, 2016 by ASP.NET   Web API  

The ModelState.IsValid property (ApiController) merely checks for a zero validation error count for a passed model while ignoring the nullability of the object instance itself.

Which basically means that a null model will always be valid regardless of its data annotations, which seems a bit ill-defined don't you think?

An obvious solution is to simply do a null check on the model, a more elegant solution is to make use of action filters, allowing us to perform certain actions before or after an action is invoked.

Have a look at the following piece of code.

public class NullModelStateActionFilter : ActionFilterAttribute
{
    public bool ReturnsBadRequest { get; set; } = false;

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ActionDescriptor.GetCustomAttributes<NullableModelAttribute>().Any() && actionContext.ActionArguments.ContainsValue(null))
        {
            actionContext.ModelState.AddModelError("Error", "Null Model Not Allowed");

            if (ReturnsBadRequest)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse
                    (HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
}


The action filter defined in the preceding snippet basically firstly checks for the presence of the NullableModelAttribute (as defined in the snippet below).

[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class NullableModelAttribute : Attribute { }

This allows us to skip the model null check for certain actions if we're required to, since we're applying this filter to all actions as seen in the GlobalConfiguration snippet below.

GlobalConfiguration.Configuration.Filters.Add(
    new NullModelStateActionFilter
    {
        ReturnsBadRequest = true
    }
);

If a null model is found (with the absence of the NullableModelAttribute), a modelstate error is added, thereby adding to the validation error count of the model (ta-dah, ModelState.IsValid is false).

Majority of the time however, we would probaly respond with a BadRequest if we're receiving invalid model states, hence the addition of the ReturnsBadRequest property in the action filter.

Note that this essentially is altering the default behavior of your controller actions, so take care when following this approach.

Well.... not much more to see here... now run a long Winking smile

Additional Reading

ActionFilterAttribute Class
Clean up your Web API controllers with model validation and null check filters
ModelState is valid with null model


Leave a Comment