4

I want to customize a attribute. Say

public class IdExistAttribute : ValidationAttribute
{

    protected override ValidationResult IsValid(object value,
                                                  ValidationContext validationContext)
    {
        string id= value.ToString();
        if(ListOfId.Contains(id))
        {
           return new ValidationResult("Id is already existing");
        }

        return ValidationResult.Success;
     }
 }

The question is that ListOfId is from service, I can't consume the service inside the attribute. So how to pass it from outside?

I want to use the attribute as

private string _id;
[IdExist]
public string Id
{
  get{return _id;}
  set{_id=value;}
}
Bigeyes
  • 1,508
  • 2
  • 23
  • 42

1 Answers1

1

ValidationContext provide access to the registered dependency injection container via GetService.

Quoting Andrew Lock:

As you can see, you are provided a ValidationContext as part of the method call. The context object contains a number of properties related to the object currently being validated, and also this handy number:

public object GetService(Type serviceType);

So you can use ValidationContext like so:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var service = (IExternalService) validationContext
                         .GetService(typeof(IExternalService));
    // use service
}
Community
  • 1
  • 1
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • Can we just pass the list value to attribute? Because I can get the value in my model class. I don't have something like `IExternalService` – Bigeyes Aug 31 '18 at 01:38
  • You can only pass compile-time values into an attribute [declaration], unfortunately. The only other option is to use a `static` value on `IdExistAttribute ` and then set that before the attribute is used. I'd recommend creating a service for this, if at all possible. – ProgrammingLlama Aug 31 '18 at 01:41
  • The drawback is if the property changed, I have to call the service to get the same value again. It has the performance issue. Maybe I shouldn't use the attribute? Maybe there is another way for the validation? – Bigeyes Aug 31 '18 at 10:45
  • Please see https://stackoverflow.com/questions/44848134/custom-validation-based-on-other-value – Bigeyes Aug 31 '18 at 13:20