0

I want to make a custom validation attribute in .NET Core called CheckIfEmailExists. I want to make sure the user is not in my database already. So this is my create user view model:

public class CreateUserViewModel
{
    public readonly UserManager userManager;

    public CreateUserViewModel()
    {
    }

    public ExtendedProfile ExtendedProfile { get; set; }

    public User User { get; set; }

    public int SchemeId { get; set; }

    public SelectList Schemes { get; set; }

    [Required]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [CheckIfEmailExists()]
    [Display(Name = "Email Address")]
    public string Email { get; set; }

    [DataType(DataType.EmailAddress)]
    [Display(Name = "Confirm Email Address")]
    public string ConfirmEmail { get; set; }

}

Here is my custom validation:

public class CheckIfEmailExists : ValidationAttribute
{
    private readonly UserManager _userManager;

    public CheckIfEmailExists(UserManager userManager)
    {
        var _userManager = userManager;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var user = (User)validationContext.ObjectInstance;

        var result = _userManager.FindByEmailAsync(user.Email).Result;

        //do something 

        return ValidationResult.Success;
    }
}

I get an error when I add my custom validation on my email property, the error is that I must pass in the usermanager object to the custom class constructor.

Why doesn't my app just inject the object itself?

Is there a way I can create a user manager object in my custom class without coupling the classes?

Should I only access my database in my controller?

TylerH
  • 20,799
  • 66
  • 75
  • 101
SmallWorld
  • 81
  • 1
  • 6
  • Try this answer: https://stackoverflow.com/questions/39627956/inject-dependencies-into-validation-attribute-web-api-asp-net-core – Nikki9696 Jun 01 '20 at 21:15

1 Answers1

0

The comment above from Nikki9696 helped me and now I know how to get my user manager and dbcontext in my custom validation attribute.

public class IsEmailInDatabase : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var context = (DatabaseContext)validationContext.GetService(typeof(DatabaseContext));

        if (value == null)
        {
            return null;
        }
        else
        {
            var results = context.Users.AnyAsync(x => x.Email == value.ToString());

            if (results.Result)
            {
                return new ValidationResult("This email address already exists in our database");
            }

            return null;
        }
    }
}
SmallWorld
  • 81
  • 1
  • 6