ASP.NET MVC Validation Groups?

前端 未结 2 1552
执念已碎
执念已碎 2020-12-14 21:13

I have a form in which I would like to require different fields depending on which submit button is pressed. Example: Field A is required if you press Submit Button 1, but

2条回答
  •  执念已碎
    2020-12-14 22:07

    How about a custom validation attribute with client validation enabled (so you get both client and server validation)? The solution below uses jQuery unobtrusive validation. To use this you will need to give all your buttons specific names and pass the name to the validation attribute. The button will also need to have a value of some sort so it can be posted back (so the server side code can test it, i.e. ). I haven't tested this code, so I'm not sure if it runs out of the box. You may need to make some mods:

    The validation attribute for your model:

    public class RequiredIfButtonClickedAttribute : ValidationAttribute, IClientValidatable
    {
        private RequiredAttribute _innerAttribute = new RequiredAttribute();
        public string ButtonName { get; set; }
    
        public RequiredIfButtonClickedAttribute(string buttonName)
        {
            ButtonName = buttonName;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if ((value == null && !string.IsNullOrEmpty(HttpContext.Current.Request.Form[ButtonName])))
            {
                if (!_innerAttribute.IsValid(value))
                {
                    return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
                }
            }
    
            return ValidationResult.Success;
        }
    
        #region IClientValidatable Members
    
        public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule() { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "requiredifbuttonclicked" };
            rule.ValidationParameters.Add("buttonname", ButtonName);
            yield return rule;
        }
    
        #endregion
    }
    

    The client script:

    /// 
    /// 
    
    // When a button is clicked remove the clicked button class from all buttons and add it to the on that was clicked
    $(":submit").click(function () {
        $(":submit").removeClass('clickedButton');
        $(this).addClass('clickedButton');
    });
    
    $.validator.addMethod('requiredifbuttonclicked',
        function (value, element, parameters) {
    
            // if the condition is true, reuse the existing 
            // required field validator functionality
            if ($(".clickedButton").val("name") === parameters['buttonname'])
                return $.validator.methods.required.call(
                  this, value, element, parameters);
    
            return true;
        }
    );
    
    $.validator.unobtrusive.adapters.add(
        'requiredifbuttonclicked',
        ['buttonname'],
        function (options) {
            options.rules['requiredifbuttonclicked'] = {
                buttonname: options.params['buttonname']
            };
            options.messages['requiredifbuttonclicked'] = options.message;
    });
    

    And use it like this:

    [RequiredIfButtonClicked("myButtonName")]
    public string Name { get; set; }
    

提交回复
热议问题