Cannot run an action filter before ModelStateInvalidFilter
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
I'm trying to add an action filter that logs validation errors (because `ModelStateInvalidFilter` only logs the fact that there was a validation error, but not the error details).
I added my filter globally in `MvcOptions.Filters`, but my filter is never called. I assumed this was because it was short-circuited by `ModelStateInvalidFilter`, which has an `Order` of `-2000`. So I implemented `IOrderedFilter` in my filter, with an `Order` of -3000, so that it would run before `ModelStateInvalidFilter`. However, my filter is still not called; in fact, even the `Order` property is never called either.
It looks like a bug to me. Why can't I add a filter that runs before `ModelStateInvalidFilter`?
### Expected Behavior
An action filter with an `IOrderedFilter.Order` lower than `ModelStateInvalidFilter` should run before it.
### Steps To Reproduce
Create the following filter:
```csharp
public class ModelStateErrorFilter : IActionFilter, IOrderedFilter
{
private readonly ILogger _logger;
public ModelStateErrorFilter(ILogger logger)
{
_logger = logger;
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid)
return;
var errors = context.ModelState.ToDictionary(
kvp => kvp.Key,
kvp => string.Join(";", kvp.Value?.Errors.Select(e => e.ErrorMessage) ?? Enumerable.Empty()));
_logger.LogInformation("The ModelState for this request has errors: {Errors}", errors);
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
// To execute before ModelStateInvalidFilter, otherwise it would be short-circuited
public int Order => -3000;
}
```
Add it as a global filter:
```csharp
builder.Services.AddControllers(options =>
{
options.Filters.Add();
});
```
Run the app, and send a request with model state errors
### Exceptions (if any)
_No response_
### .NET Version
7.0.400
### Anything else?
A possible workaround is to disable `ModelStateInvalidFilter` with this:
```csharp
.ConfigureApiBehaviorOptions(options => options.SuppressModelStateInvalidFilter = true)
```
and call `ApiBehaviorOptions.InvalidModelStateResponseFactory` myself to set the result.
It's not ideal. I'd rather not reimplement `ModelStateInvalidFilter` myself, and it shouldn't be necessary anyway.
Contributor guide
Assessment
This issue has not been assessed yet.