asp.net-mvc Fluent 验证自定义验证规则

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9367096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:45:17  来源:igfitidea点击:

Fluent validation custom validation rules

asp.net-mvcasp.net-mvc-3fluentvalidation

提问by Evgeny Levin

I have model:

我有型号:

[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; }
}

And validator for model:

和模型验证器:

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.");
    }
}

I have validator factory, that should resolve dependency:

我有验证器工厂,应该解决依赖关系:

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);
    }
}

I have IUserService, that has methods IsUsernameUnique(string name)and IsEmailUnique(string email)` and want to use it in my validator class (model should be valid only if it have unique username and email).

我有 IUserService,它有方法IsUsernameUnique(string name)和 IsEmailUnique(string email)` 并想在我的验证器类中使用它(模型只有在具有唯一的用户名和电子邮件时才有效)。

  1. how to use my service for validation?
  2. is it possible to register multiple Regular Expression Rules with different error messages? will it work on client side? (if no, how to create custom validation logic for it?)
  3. is validation on server side will work automatically before model pass in action method, and it is enough to call ModelState.IsValid property, or I need to do something more? UPDATE
  4. is it possible to access to all properties of model when validate some property? (for example I want to compare Password and ConfirmPassword when register)
  1. 如何使用我的服务进行验证?
  2. 是否可以使用不同的错误消息注册多个正则表达式规则?它会在客户端工作吗?(如果不是,如何为其创建自定义验证逻辑?)
  3. 服务器端的验证是否会在模型传入操作方法之前自动工作,调用 ModelState.IsValid 属性就足够了,还是我需要做更多的事情? 更新
  4. 验证某些属性时是否可以访问模型的所有属性?(例如我想在注册时比较密码和确认密码)

回答by Darin Dimitrov

1) how to use my service for validation?

1) 如何使用我的服务进行验证?

You could use the Mustrule:

您可以使用以下Must规则:

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

2) is it possible to register multiple Regular Expression Rules with different error messages? will it work on client side? (if no, how to create custom validation logic for it?)

2) 是否可以注册多个具有不同错误消息的正则表达式规则?它会在客户端工作吗?(如果不是,如何为其创建自定义验证逻辑?)

No, you can have only one validation type per property

不,每个属性只能有一种验证类型

if no, how to create custom validation logic for it?

如果没有,如何为其创建自定义验证逻辑?

You could use the Must rule:

您可以使用必须规则:

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

3) is validation on server side will work automatically before model pass in action method, and it is enough to call ModelState.IsValid property, or I need to do something more?

3)服务器端的验证是否会在模型传入动作方法之前自动工作,调用 ModelState.IsValid 属性就足够了,还是我需要做更多的事情?

Yes, absolutely. Your controller action could look like this:

是的,一点没错。您的控制器操作可能如下所示:

[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) is it possible to access to all properties of model when validate some property? (for example I want to compare Password and ConfirmPassword when register)

4) 验证某些属性时是否可以访问模型的所有属性?(例如我想在注册时比较密码和确认密码)

Yes, of course:

是的当然:

RuleFor(x => x.ConfirmPassword)
    .Equal(x => x.Password)
    .WithMessage("Passwords do not match");

回答by MovGP0

a nicer variant is to use a RuleBuilderExtension:

一个更好的变体是使用一个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;
    }

This way it gets trivial to use:

这样就可以轻松使用:

RuleFor(x => x.Password).Password();