私はモデルを持っています:
_[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);
}
}
_
メソッドIsUsernameUnique(string name)
とIsEmailUnique(string email) `を持つIUserServiceがあり、それをバリデータークラスで使用したいと考えています(モデルは一意のユーザー名と電子メールがある場合にのみ有効である必要があります)。
1)検証のために私のサービスを使用する方法は?
Must
ルールを使用できます。
RuleFor(x => x.Email)
.NotEmpty()
.WithMessage("Email is required.")
.EmailAddress()
.WithMessage("Invalid email format.")
.Must(userService.IsEmailUnique)
.WithMessage("Email already taken");
2)異なるエラーメッセージで複数の正規表現ルールを登録することは可能ですか?クライアント側で動作しますか? (いいえの場合、カスタム検証ロジックを作成する方法は?)
いいえ、プロパティごとに1つの検証タイプしか持てません
いいえの場合、カスタム検証ロジックを作成する方法は?
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");
}
更新:
4)一部のプロパティを検証するときに、モデルのすべてのプロパティにアクセスすることは可能ですか? (たとえば、登録時にパスワードとConfirmPasswordを比較したい)
はい、もちろん:
RuleFor(x => x.ConfirmPassword)
.Equal(x => x.Password)
.WithMessage("Passwords do not match");
より良い変形は、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();