Expose IoC to IPropertyValidationFilter.ShouldValidateEntry for more flexible ModelState validation #26580
Labels
affected-few
This issue impacts only small number of customers
area-mvc
Includes: MVC, Actions and Controllers, Localization, CORS, most templates
enhancement
This issue represents an ask for new feature or an enhancement to an existing one
feature-model-binding
severity-minor
This label is used by an internal tool
Milestone
The problem
In the JsonApiDotNetCore framework which I'm maintaining, there is a problem with ModelState validation when using the RequiredAttribute. The framework implements the json:api specification which allows for partial patching, and validation does not work well with that.
Consider the model
Article
with a to-one relationship toAuthor
, withRequiredAttributes
on all properties. Then, for example, in aPATCH /articles
request , we require the following behaviourArticle.*
should ONLY be validated if they are targeted explicitly by the request bodyArticle.Author.*
should NEVER be validated because in the json:api spec it is supported to assign relationships up to 1 layer deep, but it is not allowed to simultaneously update properties of that relationshipOn the other hand, for a
POST /articles
request, allArticle.*
properties should always be validated.I have tried to implement this behaviour by using IPropertyValidationFilter.ShouldValidateEntry(ValidationEntry entry, ValidationEntry parentEntry) (this is my custom IModelMetadataProvider that does the trick).
Currently IPropertyValidationFilter.ShouldValidateEntry(ValidationEntry entry, ValidationEntry parentEntry) allows me to deduce where I am in the object model graph through the Entry.Key property. With this I can successfully ignore
Article.Author.*
. But I also need access toHttpContextAccessor
to figure out if the request isPATCH
/POST
. This is currently not possible because the IoC is not passed along.Additionally I also need access to IoC for other json:api specific metadata about the request scope. Eg. if the endpoint is a ../relationships/... endpoint, in which case validation should never occur, regardless if
POST
orPATCH
.Solution
I would love to see the IoC being exposed to
IPropertyValidationFilter
.Proposed approach:
In IPropertyValidationFilter.cs:
Then,
PropertyValidationFilterContext
would look something like:And for ValidationVisitor.VisitChildren(IValidationStrategy):
Additional context
Currently I can work around this problem by using a custom ValidationVisitor that calls my
IPropertyValidationFilter
with a reference toIServiceProvider
. This is a bit tedious because the only way to have my application use this one instead of the built-in visitor implementation requires me to register a custom ObjectModelValidator. For this implementation I need pretty much everything from DefaultObjectValidator but this type is internal, so I need to copy-paste its internals which I think is not a good thing to do.If the idea is approved, I would love to make a PR for this myself.
Related issue in JADNC framework: json-api-dotnet/JsonApiDotNetCore#847
The text was updated successfully, but these errors were encountered: