Validate checkbox on the client with FluentValidation/MVC 3

前端 未结 4 1663
迷失自我
迷失自我 2020-12-14 10:15

I am trying to validate if a check box is checked on the client using FluentValidation. I can\'t figure it our for the life of me.

Can it be done using unobtrusive v

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-14 11:01

    I am coding in ASP.NET MVC5 and Darin's code produces a javascript error on the lines that reference value.ToLowerCase() when a checkbox is involved. Another issue is that this code invalidates the client side equality comparison between two properties. It only seems to work when comparing against a literal value...That may have been his intent, but I need it to work for both situations:

    Here's one possible workaround, that involves only two changes to Darin's answer:

    First, I updated the javascript function with the following.

    $.validator.addMethod('equaltovalue', function (value, element, params) {
        if ($(element).is(':checkbox')) {
            value = $(element).is(':checked') ? "true" : "false";
        }
        return params.valuetocompare.toLowerCase() === value.toLowerCase();
    });
    

    Secondly, I updated EqualToValueFluentValidationPropertyValidator with the following:

    public class EqualToValueFluentValidationPropertyValidator : FluentValidationPropertyValidator
    {
        EqualValidator EqualValidator 
        {
            get { return (EqualValidator)Validator; }
        }
    
        public EqualToValueFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator) : base(metadata, controllerContext, rule, validator) {
            ShouldValidate = false;
        }
    
        public override IEnumerable GetClientValidationRules() {
            if (!ShouldGenerateClientSideRules()) yield break;
    
            var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;
            if(propertyToCompare != null) {
                // If propertyToCompare is not null then we're comparing to another property.
                // If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
                // We only care about property comparisons in this case.
    
                var comparisonDisplayName =
                    ValidatorOptions.DisplayNameResolver(Rule.TypeToValidate, propertyToCompare, null)
                    ?? propertyToCompare.Name.SplitPascalCase();
    
                var formatter = new MessageFormatter()
                    .AppendPropertyName(Rule.GetDisplayName())
                    .AppendArgument("ComparisonValue", comparisonDisplayName);
    
    
                string message = formatter.BuildMessage(EqualValidator.ErrorMessageSource.GetString());
                yield return new ModelClientValidationEqualToRule(message, CompareAttribute.FormatPropertyForClientValidation(propertyToCompare.Name)) ;
            }
            else
            {
                var validator = (EqualValidator)Validator;
    
                var errorMessage = new MessageFormatter()
                    .AppendPropertyName(Rule.GetDisplayName())
                    .AppendArgument("ValueToCompare", validator.ValueToCompare)
                    .BuildMessage(validator.ErrorMessageSource.GetString());
    
                var rule = new ModelClientValidationRule();
                rule.ErrorMessage = errorMessage;
                rule.ValidationType = "equaltovalue";
                rule.ValidationParameters["valuetocompare"] = validator.ValueToCompare;
                yield return rule;
            }
        }
    }
    

    This code was copied from the EqualToFluentValidationPropertyValidator internal class in the fluentvalidation source, and I added Darin's logic after the else. This allows the client-side validation to work for property comparisons as well as value comparisons...I'm not sure if this is a great approach since you're basically overriding the built-in equality validator and it may break in future releases of fluent validation....but Darin's answer has the same issue.

    There might be better ways to handle this. If somebody knows of a way to directly include the logic from the internal EqualToFluentValidationPropertyValidator class, then I'd love to hear it.

提交回复
热议问题