monty
monty

Reputation: 8745

.NET core validation attributes based on configuration values

I am looking for a way to inject values from the configuration (options) into the parameters of validation attributes.

The scenario where this hit me was the scaffolded identity UI.

It gives the possibility to configure options about the password length. But changes aren't respected on the generated register page. This is because on the page the values of the validation attributes there are hardcoded.

Anyone know if this is even possible?

Upvotes: 1

Views: 2102

Answers (2)

zekeriya kocairi
zekeriya kocairi

Reputation: 346

If i'm not wrong, you are trying to do some kind a thing below which is not possible :

public int passLength = 3;
public class Person
{
  [MaxLength(passLength)]
  public DateTime? DateOfBirth { get; set; }
}

There is no workaround for this as far as i know. You can try custom validator and use Configuration service as you wish. You can check this sample code

public class CustomPasswordAttribute : ValidationAttribute
{
  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    var configuration = (IConfiguration)validationContext
            .GetService(typeof(IConfiguration));

    if (!(value is String)) 
    {
      return new ValidationResult("Should be string");
    }

    int.TryParse(configuration["Validation:PasswordLength"], out int passLength);

    if (value.ToString().Length != passLength)
    {
      return new ValidationResult("Wrong Length");
    }

    return ValidationResult.Success;
  }
}

public class UserModel
{
  [CustomPassword]
  public string Password { get; set; }
}

Upvotes: 5

Rosco
Rosco

Reputation: 2474

It is possible to validate the password using the options set in startup.

Here is an example for razor pages where the password is checked with multiple validators and any errors are added into the ModelState where they will appear in a ValidationSummary.

foreach (var validator in _userManager.PasswordValidators)
{
    var passCheck = await validator.ValidateAsync(_userManager, null, Input.Password);
    if (!passCheck.Succeeded)
    {
        foreach (var error in passCheck.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
        return Page();
    }
}

So the simple validations will be performed client side, then this code will run server side to enforce the password options.

Upvotes: 2

Related Questions