I'm building a Custom Validation Attribute in ASP.NET Core WebAPI. I need to access IDataProtector in my validator and another service I'm using to access the database. I've searched and wasn't ab;e to find any documentation for this. ActionFilters have the option of using ServiceFilter but there doesn't seem to be any option for Validation Attribute. Any ideas?
-
1You should not inject dependencies into attributes as expressed [here](https://stackoverflow.com/a/29916075/264697), [here](http://blog.ploeh.dk/2014/06/13/passive-attributes/) and [here](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=97). – Steven Sep 26 '16 at 17:06
4 Answers
Use the GetService() method of the ValidationContext to get your database. i.e.
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
MyDbContext db = (MyDbContext) validationContext.GetService(typeof(MyDbContext));
//...
}

- 311
- 3
- 4
-
5And because the `ValidationContext` implements `IServiceProvider`, adding `using Microsoft.Extensions.DependencyInjection` will add the rest of the useful extensions to allow `validationContext.GetService
()` without explicit casting. – Stoyan Dimov Nov 02 '18 at 09:59 -
You can override IsValid method and use validationContext to resolve dependency:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var service = (IExternalService) validationContext.GetService(typeof(IExternalService));
// use service
}

- 536
- 5
- 21
-
that's somehow, isn't cool, it returns 400 HTTP error, instead of going through controller, ModelState.IsValid(), I need to access the bool returning one, that microsoft used to override in required and etc... – Hassan Faghihi Oct 03 '20 at 10:44
We had a similar requirement where additional data was needed to be passed to an attribute to provide enough context for it to perform the validation.
We came up with a way to build up a context object which could be passed to attributes. I blogged about it here.
We are using the async api to perform data access which presented some additional challenges.

- 973
- 7
- 20
Because validation attributes are typically defined on properties, they can't receive a reference via the constructor. At best if you did really deep into model binding, there may be something to customize to allow property injection, but most practically I just get a reference to the dependency resolver in the Validate method, and call the appropriate method.

- 50,520
- 35
- 148
- 257
-
5This answer does not answer anything, it implies it is not possible or the mechanism is obscure. – Paulo Neves Aug 11 '20 at 15:16