Свободная проверка пользовательских правил проверки - PullRequest
8 голосов
/ 20 февраля 2012

У меня есть модель:

[Validator(typeof(RegisterValidator))]
public class RegisterModel
{
    public string Name { get; set; }

    public string Email { get; set; }

    public string Password { get; set; }

    public string ListOfCategoriess { get; set; }
}

И валидатор для модели:

public class RegisterValidator:AbstractValidator<RegisterModel>
{
    public RegisterValidator(IUserService userService)
    {
        RuleFor(x => x.Name).NotEmpty().WithMessage("User name is required.");
        RuleFor(x => x.Email).NotEmpty().WithMessage("Email is required.");
        RuleFor(x => x.Email).EmailAddress().WithMessage("Invalid email format.");
        RuleFor(x => x.Password).NotEmpty().WithMessage("Password is required.");
        RuleFor(x => x.ConfirmPassword).NotEmpty().WithMessage("Please confirm your password.");
    }
}

У меня есть фабрика валидаторов, которая должна разрешать зависимость:

public class WindsorValidatorFactory : ValidatorFactoryBase 
{
    private readonly IKernel kernel;

    public WindsorValidatorFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public override IValidator CreateInstance(Type validatorType)
    {
        if (validatorType == null)
            throw new Exception("Validator type not found.");
        return (IValidator) kernel.Resolve(validatorType);
    }
}

У меня есть IUserService, у которого есть методы IsUsernameUnique(string name) и IsEmailUnique (string email) `, и я хочу использовать его в моем классе валидатора (модель должна быть действительной, только если у нее уникальное имя пользователя и адрес электронной почты).

  1. как использовать мой сервис для проверки?
  2. возможно ли зарегистрировать несколько правил регулярных выражений с разными сообщениями об ошибках? это будет работать на стороне клиента? (если нет, как создать для него собственную логику проверки?)
  3. - проверка на стороне сервера будет работать автоматически перед передачей модели в метод действия, и достаточно вызвать свойство ModelState.IsValid, или мне нужно сделать что-то еще? UPDATE
  4. возможно ли получить доступ ко всем свойствам модели при проверке какого-либо свойства? (например, я хочу сравнить пароль и пароль подтверждения при регистрации)

Ответы [ 2 ]

21 голосов
/ 21 февраля 2012

1) как использовать мой сервис для проверки?

Вы можете использовать правило Must:

RuleFor(x => x.Email)
    .NotEmpty()
    .WithMessage("Email is required.")
    .EmailAddress()
    .WithMessage("Invalid email format.")
    .Must(userService.IsEmailUnique)
    .WithMessage("Email already taken");

2) можно ли зарегистрировать несколько правил регулярных выражений с разными сообщениями об ошибках? это будет работать на стороне клиента? (если нет, как создать для него собственную логику проверки?)

Нет, вы можете иметь только один тип проверки для свойства

если нет, как создать для него собственную логику проверки?

Вы можете использовать правило Must:

RuleFor(x => x.Password)
    .Must(password => SomeMethodContainingCustomLogicThatMustReturnBoolean(password))
    .WithMessage("Sorry password didn't satisfy the custom logic");

3) проверка на стороне сервера будет работать автоматически до того, как модель передаст метод действия, и достаточно вызвать свойство ModelState.IsValid, или мне нужно сделать что-то еще?

Да, абсолютно. Ваше действие контроллера может выглядеть так:

[HttpPost]
public ActionResult Register(RegisterModel model)
{
    if (!ModelState.IsValid)
    {
        // validation failed => redisplay the view so that the user
        // can fix his errors
        return View(model);
    }

    // at this stage the model is valid => process it
    ...
    return RedirectToAction("Success");
}

UPDATE:

4) возможно ли получить доступ ко всем свойствам модели при проверке какого-либо свойства? (например, я хочу сравнить пароль и пароль подтверждения при регистрации)

Да, конечно:

RuleFor(x => x.ConfirmPassword)
    .Equal(x => x.Password)
    .WithMessage("Passwords do not match");
8 голосов
/ 16 июля 2017

лучший вариант - использовать RuleBuilderExtension:

public static class RuleBuilderExtensions
{
    public static IRuleBuilder<T, string> Password<T>(this IRuleBuilder<T, string> ruleBuilder, int minimumLength = 14)
    {
        var options = ruleBuilder
            .NotEmpty().WithMessage(ErrorMessages.PasswordEmpty)
            .MinimumLength(minimumLength).WithMessage(ErrorMessages.PasswordLength)
            .Matches("[A-Z]").WithMessage(ErrorMessages.PasswordUppercaseLetter)
            .Matches("[a-z]").WithMessage(ErrorMessages.PasswordLowercaseLetter)
            .Matches("[0-9]").WithMessage(ErrorMessages.PasswordDigit)
            .Matches("[^a-zA-Z0-9]").WithMessage(ErrorMessages.PasswordSpecialCharacter);
        return options;
    }

Таким образом, использование становится тривиальным:

RuleFor(x => x.Password).Password();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...