2012-02-20 123 views
7

我有模式:流利驗證自定義的驗證規則

[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(字符串電子郵件)`並且想要在我的val中使用它idator類(模型只有在具有唯一的用戶名和電子郵件時纔有效)。

  1. 如何使用我的服務進行驗證?
  2. 是否可以使用不同的錯誤消息註冊多個正則表達式規則?它會在客戶端工作嗎? (如果沒有,如何爲它創建自定義驗證邏輯?)
  3. 在服務器端驗證會在模型傳遞行爲方法之前自動工作,並且足以調用ModelState.IsValid屬性,或者我需要做更多的事情? UPDATE
  4. 是否有可能在驗證某些屬性時訪問模型的所有屬性? (例如我想比較密碼和ConfirmPassword時註冊)

回答

21

1)如何使用我的服務進行驗證?

您可以使用Must規則:

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

2)是否有可能註冊不同的錯誤消息的多個正則表達式規則?它會在客戶端工作嗎? (如果沒有,如何爲它創建自定義的驗證邏輯?)

沒有,你可以爲每個屬性

如果沒有隻有一個驗證類型,如何創建自定義的驗證邏輯呢?

您可以使用一定要排除:

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)是否有可能訪問模型時,驗證某些屬性的所有屬性? (例如,我想比較密碼和ConfirmPassword當寄存器)

是的,當然:

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

約2:我想有畝ltiple正則表達式和每個正則表達式都有自己的錯誤消息。可能嗎? – 2012-02-20 21:28:55

+0

@EvgenyLevin,我已經在我的回答中介紹了這一點:'不,每個屬性只能有一個驗證類型。所以你有兩種可能性:或者想出一個可以驗證一切的正​​則表達式,或者使用Must規則來編寫一些自定義邏輯。 – 2012-02-20 21:40:34

+0

並且我不能編寫一個以上的自定義邏輯。請看更新(點4)。 – 2012-02-21 07:08:13

4

一個更好的變種是使用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-b]").WithMessage(ErrorMessages.PasswordLowercaseLetter) 
      .Matches("[0-9]").WithMessage(ErrorMessages.PasswordDigit) 
      .Matches("[^a-zA-Z0-9]").WithMessage(ErrorMessages.PasswordSpecialCharacter); 
     return options; 
    } 

這樣,它得到微不足道的使用:

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

謝謝你的回答。 – 2017-11-24 16:24:28