C# – How to disable ModelStateInvalidFilter

There are two options for disabling ModelStateInvalidFilter:

  • Disable it globally for all actions.
  • Disable it for specific actions.

You’d do this when you want to manually perform model validation. I’ll show both options below.

Disable ModelStateInvalidFilter globally

To disable ModelStateInvalidFilter for *all* actions, set SuppressModelStateInvalidFilter=true in ConfigureApiBehaviorOptions, like this:

services.AddControllers().ConfigureApiBehaviorOptions(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});Code language: JavaScript (javascript)

Disable ModelStateInvalidFilter for specific actions

To disable ModelStateInvalidFilter selectively, you can implement an IActionModelConvention attribute that removes the filter. Then apply this attribute to the actions where you don’t want that filter.

First, implement the IActionModelConvention attribute:

using Microsoft.AspNetCore.Mvc.ApplicationModels;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class DisableInvalidModelFilterAttribute : Attribute, IActionModelConvention
{
	private const string FilterName = "ModelStateInvalidFilterFactory";
	public void Apply(ActionModel action)
	{
		//Search for the action filter and remove it
		for (var i = 0; i < action.Filters.Count; i++)
		{
			if (action.Filters[i].GetType().Name == FilterName)
			{
				action.Filters.RemoveAt(i);
				return;
			}
		}
	}
	
}
Code language: C# (cs)

Then apply this attribute to any action where you want to disable ModelStateInvalidFilter:

[ApiController]
[Route("[controller]")]
public class StocksController : ControllerBase
{
	[HttpPost]
	[DisableInvalidModelFilter]
	public IActionResult Post(StockOrder stockOrder)
	{
		return Ok(stockOrder);
	}
}
Code language: C# (cs)

The framework will run the IActionModelConvention code when the web API is initializing.

Conventions only run once

You may be wondering, won’t adding the IActionModelConvention to my actions slow down my requests? No, not really. The framework only runs these once during initialization. It doesn’t run them every time there’s a request. That’d be pretty inefficient.

Can’t use this to remove custom filters you added

Originally I tried to generalize this approach to be able to disable any action filter. But as a commenter pointed out, that didn’t work (and it somehow slipped through my original testing, sorry!). The problem is that these custom action filters aren’t in Action.Filters at the time when the IActionModelConvention is ran. So don’t try to use this approach for removing custom action filters.

4 thoughts on “C# – How to disable ModelStateInvalidFilter”

  1. I cannot make it work. When Apply() is invoked at start up, the action has no filters. When the action is called it gets the filter from the controller’s attribute. Am I missing something?

    Reply
    • You’re right. I re-tested this and confirmed it’s not working for custom action filters that I added. It only works for global action filters added by the framework:
      * ClientErrorResultFilterFactory
      * ModelStateInvalidFilterFactory

      I must’ve tested wrong originally. I’ll update the article to only refer to the case where it definitely works – for disabling ModelStateInvalidFilterFactory when it’s added globally.

      Thanks for pointing out this flaw!

      Reply

Leave a Reply to Kevin Cancel reply