Issue with chaining Required Field and Regular Expression validators for Textbox controls

后端 未结 4 1055
失恋的感觉
失恋的感觉 2021-01-19 10:55

I\'m trying to implement a form validation with ASP.net and I have tried every solution suggested here but the best one was on aspsnippets.com so far.

My code is lik

4条回答
  •  Happy的楠姐
    2021-01-19 11:43

    In addition to @MichaelLiu, You can make your own validators that inherit from the CustomValidator class and alter the rendering of the validators to make them a little easier to work with.

    For example:

    Validators.cs


    Take notice of how we add a property of CssControlErrorClass. We will use this when applying a class with the invalid input in question.

    We also set other properties so you don't have to set them everytime, ClientValidationFunction and ValidateEmptyText.

    public class RequiredFieldValidator : CustomValidator
    {
        public string CssControlErrorClass { get; set; }
    
        public RequiredFieldValidator()
        {
            ClientValidationFunction = "validators.required";
            ValidateEmptyText = true;
        }
    
        public string InitialValue
        {
            get
            {
                object o = ViewState["InitialValue"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set
            {
                ViewState["InitialValue"] = value;
            }
        }
    
        protected override void Render(HtmlTextWriter writer)
        {
            //Have to add attributes BEFORE the beginning tag is written to the stream
            writer.AddAttribute("data-errorClass", CssControlErrorClass);
            writer.AddAttribute("data-for", GetControlRenderID(ControlToValidate));
    
            base.Render(writer);
        }
    
    
    
        protected override bool EvaluateIsValid()
        {
            //Default implementation of the RequiredFieldValidation validator
            string controlValue = GetControlValidationValue(ControlToValidate);
    
            if (controlValue == null)
            {
                return true;
            }
    
            var result = (!controlValue.Trim().Equals(InitialValue.Trim()));
    
            //Check to see if validation failed, if it did, add the class to the control to validate
            if (!result)
            {
                var control = (WebControl) NamingContainer.FindControl(ControlToValidate);
    
                //Didn't look into it too much, but the validators fire twice for some reason
                if(!control.CssClass.Contains(CssControlErrorClass)) control.CssClass += " " + CssControlErrorClass;
            }
    
            return result;
        }
    }
    
    
    public class RegularExpressionValidator : CustomValidator
    {
        public string CssControlErrorClass { get; set; }
    
        public string ValidationExpression
        {
            get
            {
                object o = ViewState["ValidationExpression"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set
            {
                try
                {
                    Regex.IsMatch(String.Empty, value);
                }
                catch (Exception e)
                {
                    throw new HttpException(string.Format("{0} - {1}", "Validator_bad_regex", value), e);
                }
                ViewState["ValidationExpression"] = value;
            }
        }
    
        public RegularExpressionValidator()
        {
            ClientValidationFunction = "validators.regex";
        }
    
        protected override void Render(HtmlTextWriter writer)
        {
            //Have to add attributes BEFORE the beginning tag is written to the stream
            writer.AddAttribute("data-errorClass", CssControlErrorClass);
            writer.AddAttribute("data-regex", ValidationExpression);
            writer.AddAttribute("data-for", GetControlRenderID(ControlToValidate));
    
            base.Render(writer);
        }
    
        protected override bool EvaluateIsValid()
        {
            //Default implementation of the RegularExpressionFieldvalidator
            string controlValue = GetControlValidationValue(ControlToValidate);
            if (controlValue == null || controlValue.Trim().Length == 0)
            {
                return true;
            }
    
            try
            {
                Match m = Regex.Match(controlValue, ValidationExpression);
                var result = (m.Success && m.Index == 0 && m.Length == controlValue.Length);
    
                //Check to see if validation failed, if it did, add the class to the control to validate
                if (!result)
                {
                    var control = (WebControl) NamingContainer.FindControl(ControlToValidate);
    
                    //Didn't look into it too much, but the validators fire twice for some reason
                    if (!control.CssClass.Contains(CssControlErrorClass)) control.CssClass += " " + CssControlErrorClass;
                }
                return result;
            }
            catch
            {
                return true;
            }
        }
    }
    

    Validators.js


    Since in the previous classes we pre-defined the javascript functions, we can add a simple script like so:

    var v = window.validators = window.validators || {
        errorControlAttributeName: "data-for",
        errorClassAttributeName: "data-errorClass",
        regexAttributeName: "data-regex",
    
        required: function(src, args) {
            var controlId = src.getAttribute(v.errorControlAttributeName),
                errorClass = src.getAttribute(v.errorClassAttributeName),
                input = document.getElementById(controlId);
    
            var isValid = (args.Value !== "");
    
            v._toggleInputErrorState(input, errorClass, isValid);
    
            args.IsValid = isValid;
            return;
        },
    
        regex: function(src, args) {
            var controlId = src.getAttribute(v.errorControlAttributeName),
                errorClass = src.getAttribute(v.errorClassAttributeName),
                regexString = src.getAttribute(v.regexAttributeName),
                input = document.getElementById(controlId),
                regex = new RegExp(regexString);
    
            var isValid = regex.test(args.Value);
    
            v._toggleInputErrorState(input, errorClass, isValid);
            args.IsValid = isValid;
            return;
        },    
    
        /************* Helper functions ***********/
    
        _toggleInputErrorState: function (inputEl, errorClass, isValid) {
            if (!isValid) {
                if (!v._hasClass(inputEl, errorClass)) {
                    inputEl.className += " " + errorClass;
                }
            } else {
                if (v._hasClass(inputEl, errorClass)) {
                    //Not the most performant, but is sure is easiest
                    inputEl.className = inputEl.className.replace(" " + errorClass, "");
                }
            }
        },
    
        _hasClass: function(el, className) {
            return el.className.indexOf(className) != -1 ? true : false;
        },
    }
    

    Very simple validation library that you can easily extend with things you are actually interesting in.

    Default.aspx


    After than you can put the controls into your page:

    
    
    

    Is this the best way? Probably not, (these two use the default implementation that is given by Microsoft) there are way smarter people out there than I and I don't work with WebForms much. The biggest benefit I see is that you get some reusable code, using a familiar syntax, that will eventually contain all your validation needs versus messing around with js everytime to get the validation "rules" how you want them.

提交回复
热议问题