Class/Model Level Validation (as opposed to Property Level)? (ASP.NET MVC 2.0)

后端 未结 6 2174
忘掉有多难
忘掉有多难 2020-12-14 10:31

Basically, what the title says. I have several properties that combine together to really make one logical answer, and i would like to run a server-side validation code (tha

6条回答
  •  无人及你
    2020-12-14 11:37

    Now that you've looked at Data Annotations and arrived to the conclusion that they are not adapted to your scenario I would suggest you looking at FluentValidation, its integration with ASP.NET MVC and the way you would unit test your validation logic - you won't be disappointed (I really have nothing against Data annotations, they are great for blog posts and tutorials but once you are confronted to real world applications you quickly realize the limits).


    UPDATE:

    As requested in the comments section here's an example of using the FluentValidation framework with one server-side validation function accessing multiple properties (please don't do this as it is ugly and there's a better way):

    class AuthInfo
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string ConfirmPassword { get; set; }
    }
    
    class AuthInfoValidator : AbstractValidator
    {
        public override ValidationResult Validate(AuthInfo instance)
        {
            var result = base.Validate(instance);
            if (string.IsNullOrEmpty(instance.Username))
            {
                result.Errors.Add(new ValidationFailure("Username", "Username is required"));
            }
            if (string.IsNullOrEmpty(instance.Password))
            {
                result.Errors.Add(new ValidationFailure("Password", "Password is required"));
            }
            if (string.IsNullOrEmpty(instance.ConfirmPassword))
            {
                result.Errors.Add(new ValidationFailure("ConfirmPassword", "ConfirmPassword is required"));
            }
            if (instance.Password != instance.ConfirmPassword)
            {
                result.Errors.Add(new ValidationFailure("ConfirmPassword", "Passwords must match"));
            }
            return result;
        }
    }
    

    The more natural way to do this is the following (it is also immune to property rename as it contains no magic strings):

    class AuthInfoValidator : AbstractValidator
    {
        public AuthInfoValidator()
        {
            RuleFor(x => x.Username)
                .NotEmpty()
                .WithMessage("Username is required");
    
            RuleFor(x => x.Password)
                .NotEmpty()
                .WithMessage("Password is required");
    
            RuleFor(x => x.ConfirmPassword)
                .NotEmpty()
                .WithMessage("ConfirmPassword is required");
    
            RuleFor(x => x.ConfirmPassword)
                .Equal(x => x.Password)
                .WithMessage("Passwords must match");
        }
    }
    

提交回复
热议问题