BaseValidator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / UI / WebControls / BaseValidator.cs / 4 / BaseValidator.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
 
    using System.ComponentModel;
    using System.Drawing; 
    using System.Globalization;
    using System.Web;
    using System.Web.UI.HtmlControls;
    using System.Text.RegularExpressions; 
    using System.Text;
    using System.Security.Permissions; 
    using System.Web.Util; 

 
    /// 
    ///     Serves as the abstract base
    ///       class for validator objects.
    ///  
    [
    DefaultProperty("ErrorMessage"), 
    Designer("System.Web.UI.Design.WebControls.BaseValidatorDesigner, " + AssemblyRef.SystemDesign), 
    ]
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public abstract class BaseValidator : Label, IValidator {

        // constants for Validation script library 
        private const string ValidatorFileName = "WebUIValidation.js";
        private const string ValidatorIncludeScriptKey = "ValidatorIncludeScript"; 
        private const string ValidatorStartupScript = @" 
 
        "; 

        private bool preRenderCalled; 
        private bool isValid;
        private bool propertiesChecked;
        private bool propertiesValid;
        private bool renderUplevel; 

 
        ///  
        /// Initializes a new instance of the  class.
        ///  
        protected BaseValidator() {
            isValid = true;
            propertiesChecked = false;
            propertiesValid = true; 
            renderUplevel = false;
 
            // Default validators to Red 
            ForeColor = Color.Red;
        } 


        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never)
        ] 
        public override string AssociatedControlID { 
            get {
                return base.AssociatedControlID; 
            }
            set {
                throw new NotSupportedException(
                    SR.GetString(SR.Property_Not_Supported, 
                                                     "AssociatedControlID",
                                                     this.GetType().ToString())); 
            } 
        }
 

        /// 
        ///    Gets or sets
        ///       the text color of validation messages. 
        /// 
        [ 
        DefaultValue(typeof(Color), "Red") 
        ]
        public override Color ForeColor { 
            get {
                return base.ForeColor;
            }
            set { 
                base.ForeColor = value;
            } 
        } 

 
        /// 
        ///    Gets or sets the control to validate.
        /// 
        [ 
        WebCategory("Behavior"),
        Themeable(false), 
        DefaultValue(""), 
        IDReferenceProperty(),
        WebSysDescription(SR.BaseValidator_ControlToValidate), 
        TypeConverter(typeof(ValidatedControlConverter))
        ]
        public string ControlToValidate {
            get { 
                object o = ViewState["ControlToValidate"];
                return((o == null) ? String.Empty : (string)o); 
            } 
            set {
                ViewState["ControlToValidate"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the text for the error message. 
        ///  
        [
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue(""),
        WebSysDescription(SR.BaseValidator_ErrorMessage)
        ] 
        public string ErrorMessage {
            get { 
                object o = ViewState["ErrorMessage"]; 
                return((o == null) ? String.Empty : (string)o);
            } 
            set {
                ViewState["ErrorMessage"] = value;
            }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        [
        WebCategory("Behavior"),
        Themeable(false),
        DefaultValue(true), 
        WebSysDescription(SR.BaseValidator_EnableClientScript)
        ] 
        public bool EnableClientScript { 
            get {
                object o = ViewState["EnableClientScript"]; 
                return((o == null) ? true : (bool)o);
            }
            set {
                ViewState["EnableClientScript"] = value; 
            }
        } 
 

        ///  
        ///    Gets or sets a value that indicates whether the validation for the control is
        ///       enabled.
        /// 
        public override bool Enabled { 
            get {
                return base.Enabled; 
            } 
            set {
                base.Enabled= value; 
                // When disabling a validator, it would almost always be intended for that validator
                // to not make the page invalid for that round-trip.
                if (!value) {
                    isValid = true; 
                }
            } 
        } 

        // VSWhidbey 244999 
        internal override bool IsReloadable {
            get {
                return true;
            } 
        }
 
 
        /// 
        ///    Gets 
        ///       or sets a flag to indicate if the referenced control passed
        ///       validation.
        /// 
        [ 
        Browsable(false),
        WebCategory("Behavior"), 
        Themeable(false), 
        DefaultValue(true),
        WebSysDescription(SR.BaseValidator_IsValid), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool IsValid {
            get { 
                return isValid;
            } 
            set { 
                isValid = value;
            } 
        }


        ///  
        ///    Gets a value that indicates whether the property of the control is valid. This property is read-only.
        ///  
        protected bool PropertiesValid { 
            get {
                if (!propertiesChecked) { 
                    propertiesValid = ControlPropertiesValid();
                    propertiesChecked = true;
                }
                return propertiesValid; 
            }
        } 
 

        ///  
        ///    Gets a value that indicates whether the client's browser supports uplevel rendering. This
        ///       property is read-only.
        /// 
        protected bool RenderUplevel { 
            get {
                return renderUplevel; 
            } 
        }
 

        /// 
        ///    Gets or sets the display behavior of the
        ///       validator control. 
        /// 
        [ 
        WebCategory("Appearance"), 
        Themeable(false),
        DefaultValue(ValidatorDisplay.Static), 
        WebSysDescription(SR.BaseValidator_Display)
        ]
        public ValidatorDisplay Display {
            get { 
                object o = ViewState["Display"];
                return((o == null) ? ValidatorDisplay.Static : (ValidatorDisplay)o); 
            } 
            set {
                if (value < ValidatorDisplay.None || value > ValidatorDisplay.Dynamic) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                ViewState["Display"] = value;
            } 
        }
 
 
        /// 
        ///    Whether the validator sets focus on the control when invalid 
        /// 
        [
        WebCategory("Behavior"),
        Themeable(false), 
        DefaultValue(false),
        WebSysDescription(SR.BaseValidator_SetFocusOnError) 
        ] 
        public bool SetFocusOnError {
            get { 
                object o = ViewState["SetFocusOnError"];
                return((o == null) ? false : (bool)o);
            }
            set { 
                ViewState["SetFocusOnError"] = value;
            } 
        } 

 
        /// 
        /// Text to display for the validator when the validated control is invalid.
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(""), 
        WebSysDescription(SR.BaseValidator_Text), 
        PersistenceMode(PersistenceMode.InnerDefaultProperty)
        ] 
        public override string Text {
            // VSWhidbey 83105: Override the property only to override the description
            get {
                return base.Text; 
            }
            set { 
                base.Text = value; 
            }
        } 


        [
        WebCategory("Behavior"), 
        Themeable(false),
        DefaultValue(""), 
        WebSysDescription(SR.BaseValidator_ValidationGroup) 
        ]
        public virtual string ValidationGroup { 
            get {
                object o = ViewState["ValidationGroup"];
                return((o == null) ? string.Empty : (string)o);
            } 
            set {
                ViewState["ValidationGroup"] = value; 
            } 
        }
 

        /// 
        /// 
        ///    Adds the attributes of this control to the output stream for rendering on the 
        ///       client.
        ///  
        protected override void AddAttributesToRender(HtmlTextWriter writer) { 
            // Validators do not render the "disabled" attribute, instead they are invisible when disabled.
            bool disabled = !Enabled; 
            if (disabled) {
                Enabled = true;
            }
 
            try {
                if (RenderUplevel) { 
                    // We always want validators to have an id on the client 
                    EnsureID();
                    string id = ClientID; 

                    // DevDiv Schedule 33075: Expando attributes are added through client-side JavaScript

                    // DevDiv 33149: A backward compat. switch for Everett rendering 
                    HtmlTextWriter expandoAttributeWriter = (EnableLegacyRendering) ? writer : null;
 
                    if (ControlToValidate.Length > 0) { 
                        AddExpandoAttribute(expandoAttributeWriter, id, "controltovalidate", GetControlRenderID(ControlToValidate));
                    } 
                    if (SetFocusOnError) {
                        AddExpandoAttribute(expandoAttributeWriter, id, "focusOnError", "t", false);
                    }
                    if (ErrorMessage.Length > 0) { 
                        AddExpandoAttribute(expandoAttributeWriter, id, "errormessage", ErrorMessage);
                    } 
                    ValidatorDisplay display = Display; 
                    if (display != ValidatorDisplay.Static) {
                        AddExpandoAttribute(expandoAttributeWriter, id, "display", PropertyConverter.EnumToString(typeof(ValidatorDisplay), display), false); 
                    }
                    if (!IsValid) {
                        AddExpandoAttribute(expandoAttributeWriter, id, "isvalid", "False", false);
                    } 
                    if (disabled) {
                        AddExpandoAttribute(expandoAttributeWriter, id, "enabled", "False", false); 
                    } 
                    if (ValidationGroup.Length > 0) {
                        AddExpandoAttribute(expandoAttributeWriter, id, "validationGroup", ValidationGroup); 
                    }
                }

                base.AddAttributesToRender(writer); 
            }
            finally { 
                // If exception happens above, we can still reset the property if needed 
                if (disabled) {
                    Enabled = false; 
                }
            }
        }
 
        internal void AddExpandoAttribute(HtmlTextWriter writer, string controlId, string attributeName, string attributeValue) {
            AddExpandoAttribute(writer, controlId, attributeName, attributeValue, true); 
        } 

        internal void AddExpandoAttribute(HtmlTextWriter writer, string controlId, string attributeName, string attributeValue, bool encode) { 
            AddExpandoAttribute(this, writer, controlId, attributeName, attributeValue, encode);
        }

        internal static void AddExpandoAttribute(Control control, HtmlTextWriter writer, string controlId, string attributeName, string attributeValue, bool encode) { 
            // if writer is not null, assuming the expando attribute is written out explicitly
            if (writer != null) { 
                writer.AddAttribute(attributeName, attributeValue, encode); 
            }
            else { 
                Debug.Assert(control != null);
                Page page = control.Page;
                Debug.Assert(page != null);
 
                // Cannot use the overload of RegisterExpandoAttribute that takes a Control, since that method only works with AJAX 3.5,
                // and we need to support Validators in AJAX 1.0 (Windows OS Bugs 2015831). 
                if (!page.IsPartialRenderingSupported) { 
                    // Fall back to ASP.NET 2.0 behavior
                    page.ClientScript.RegisterExpandoAttribute(controlId, attributeName, attributeValue, encode); 
                }
                else {
                    // Atlas Partial Rendering support
                    // ScriptManager exists, so call its instance' method for script registration 
                    ValidatorCompatibilityHelper.RegisterExpandoAttribute(control, controlId, attributeName, attributeValue, encode);
                } 
            } 
        }
 

        /// 
        ///     Determines if the referenced control
        ///       has a validation property. 
        /// 
        protected void CheckControlValidationProperty(string name, string propertyName) { 
            // get the control using the relative name 
            Control c = NamingContainer.FindControl(name);
            if (c == null) { 
                throw new HttpException(
                                       SR.GetString(SR.Validator_control_not_found, name, propertyName, ID));
            }
 
            // get its validation property
            PropertyDescriptor prop = GetValidationProperty(c); 
            if (prop == null) { 
                throw new HttpException(
                                       SR.GetString(SR.Validator_bad_control_type, name, propertyName, ID)); 
            }

        }
 

        ///  
        ///    Determines if the properties are valid so that validation 
        ///       is meaningful.
        ///  
        protected virtual bool ControlPropertiesValid() {
            // Check for blank control to validate
            string controlToValidate = ControlToValidate;
            if (controlToValidate.Length == 0) { 
                throw new HttpException(
                                       SR.GetString(SR.Validator_control_blank, ID)); 
            } 

            // Check that the property points to a valid control. Will throw and exception if not found 
            CheckControlValidationProperty(controlToValidate, "ControlToValidate");

            return true;
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        protected virtual bool DetermineRenderUplevel() {

            // must be on a page
            Page page = Page; 
            if (page == null || page.RequestInternal == null) {
                return false; 
            } 

            // Check the browser capabilities 
            return (EnableClientScript
                        && page.Request.Browser.W3CDomVersion.Major >= 1
                        && page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1, 2)) >= 0);
        } 

 
        ///  
        ///     TDB. Not
        ///       coded yet. 
        /// 
        protected abstract bool EvaluateIsValid();

 
        /// 
        ///    Gets the control indicated by the relative name and 
        ///    returns an ID that can be used on the client. 
        /// 
        protected string GetControlRenderID(string name) { 

            // get the control using the relative name
            Control c = FindControl(name);
            if (c == null) { 
                Debug.Fail("We should have already checked for the presence of this");
                return String.Empty; 
            } 
            return c.ClientID;
        } 



        ///  
        ///     Gets the validation value of the control
        ///       named relative to the validator. 
        ///  
        protected string GetControlValidationValue(string name) {
 
            // get the control using the relative name
            Control c = NamingContainer.FindControl(name);
            if (c == null) {
                return null; 
            }
 
            // get its validation property 
            PropertyDescriptor prop = GetValidationProperty(c);
            if (prop == null) { 
                return null;
            }

            // get its value as a string 
            object value = prop.GetValue(c);
            if (value is ListItem) { 
                return((ListItem) value).Value; 
            }
            else if (value != null) { 
                return value.ToString();
            }
            else {
                return string.Empty; 
            }
        } 
 

        ///  
        ///    Helper function to get the validation
        ///       property of a control if it exists.
        /// 
        public static PropertyDescriptor GetValidationProperty(object component) { 
            ValidationPropertyAttribute valProp = (ValidationPropertyAttribute)TypeDescriptor.GetAttributes(component)[typeof(ValidationPropertyAttribute)];
            if (valProp != null && valProp.Name != null) { 
                return TypeDescriptor.GetProperties(component, null)[valProp.Name]; 
            }
            return null; 
        }


        ///  
        /// 
        ///     Registers the validator on the page. 
        ///  
        protected internal override void OnInit(EventArgs e) {
            base.OnInit(e); 
            Page.Validators.Add(this);
        }

 
        /// 
        ///  
        ///     Un-registers the validator on the page. 
        /// 
        protected internal override void OnUnload(EventArgs e) { 
            if (Page != null) {
                Page.Validators.Remove(this);
            }
            base.OnUnload(e); 
        }
 
 
        /// 
        ///  
        ///    Checks the client brower and configures the
        ///       validator for compatibility prior to rendering. 
        /// 
 
        protected internal override void OnPreRender(EventArgs e) {
            base.OnPreRender(e); 
            preRenderCalled = true; 

            // force a requery of properties for render 
            propertiesChecked = false;

            // VSWhidbey 83130, we should check properties during PreRender so
            // the checking applies to all deviecs. 
            if (!PropertiesValid) {
                // In practice the call to the property PropertiesValid would 
                // throw if bad things happen. 
                Debug.Assert(false, "Exception should have been thrown if properties are invalid");
            } 

            // work out uplevelness now
            renderUplevel = DetermineRenderUplevel();
 
            if (renderUplevel) {
                RegisterValidatorCommonScript(); 
            } 
        }
 

        /// 
        ///    
        ///       Registers code on the page for client-side validation. 
        ///    
        ///  
        protected void RegisterValidatorCommonScript() { 
            const string onSubmitScriptKey = "ValidatorOnSubmit";
            const string onSubmitScript = "if (typeof(ValidatorOnSubmit) == \"function\" && ValidatorOnSubmit() == false) return false;"; 

            // Cannot use the overloads of Register* that take a Control, since these methods only work with AJAX 3.5,
            // and we need to support Validators in AJAX 1.0 (Windows OS Bugs 2015831).
            if (!Page.IsPartialRenderingSupported) { 
                if (Page.ClientScript.IsClientScriptBlockRegistered(typeof(BaseValidator), ValidatorIncludeScriptKey)) {
                    return; 
                } 

                Page.ClientScript.RegisterClientScriptResource(typeof(BaseValidator), ValidatorFileName); 
                Page.ClientScript.RegisterStartupScript(typeof(BaseValidator), ValidatorIncludeScriptKey, ValidatorStartupScript);
                Page.ClientScript.RegisterOnSubmitStatement(typeof(BaseValidator), onSubmitScriptKey, onSubmitScript);
            }
            else { 
                // Register the original validation scripts but through the new ScriptManager APIs
                ValidatorCompatibilityHelper.RegisterClientScriptResource(this, typeof(BaseValidator), ValidatorFileName); 
                ValidatorCompatibilityHelper.RegisterStartupScript(this, typeof(BaseValidator), ValidatorIncludeScriptKey, ValidatorStartupScript, false); 
                ValidatorCompatibilityHelper.RegisterOnSubmitStatement(this, typeof(BaseValidator), onSubmitScriptKey, onSubmitScript);
            } 
        }


        ///  
        /// Registers array declarations using the default array,  .
        ///  
        protected virtual void RegisterValidatorDeclaration() { 
            const string arrayName = "Page_Validators";
            string element = "document.getElementById(\"" + ClientID + "\")"; 

            // Cannot use the overloads of Register* that take a Control, since these methods only work with AJAX 3.5,
            // and we need to support Validators in AJAX 1.0 (Windows OS Bugs 2015831).
            if (!Page.IsPartialRenderingSupported) { 
                Page.ClientScript.RegisterArrayDeclaration(arrayName, element);
            } 
            else { 
                ValidatorCompatibilityHelper.RegisterArrayDeclaration(this, arrayName, element);
 
                // Register a dispose script to make sure we clean up the page if we get destroyed
                // during an async postback.
                // We should technically use the ScriptManager.RegisterDispose() method here, but the original implementation
                // of Validators in AJAX 1.0 manually attached a dispose expando.  We added this code back in the product 
                // late in the Orcas cycle, and we didn't want to take the risk of using RegisterDispose() instead.
                // (Windows OS Bugs 2015831) 
                ValidatorCompatibilityHelper.RegisterStartupScript(this, typeof(BaseValidator), ClientID + "_DisposeScript", 
                    String.Format(
                        CultureInfo.InvariantCulture, 
                        @"
document.getElementById('{0}').dispose = function() {{
    Array.remove({1}, document.getElementById('{0}'));
}} 
",
                        ClientID, arrayName), true); 
            } 
        }
 

        /// 
        /// 
        ///    Displays the control on the client. 
        /// 
        protected internal override void Render(HtmlTextWriter writer) { 
            bool shouldBeVisible; 

            // VSWhidbey 347677, 398978: Backward Compat.: Skip property checking if the 
            // validator doesn't have PreRender called and it is not in page control tree.
            if (DesignMode || (!preRenderCalled && Page == null)) {
                // This is for design time. In this case we don't want any expandos
                // created, don't want property checks and always want to be visible. 
                propertiesChecked = true;
                propertiesValid = true; 
                renderUplevel = false; 
                shouldBeVisible = true;
            } 
            else {
                shouldBeVisible = Enabled && !IsValid;
            }
 
            // No point rendering if we have errors
            if (!PropertiesValid) { 
                return; 
            }
 
            // Make sure we are in a form tag with runat=server.
            if (Page != null) {
                Page.VerifyRenderingInServerForm(this);
            } 

            // work out what we are displaying 
            ValidatorDisplay display = Display; 
            bool displayContents;
            bool displayTags; 
            if (RenderUplevel) {
                displayTags = true;
                displayContents = (display != ValidatorDisplay.None);
            } 
            else {
                displayContents = (display != ValidatorDisplay.None && shouldBeVisible); 
                displayTags = displayContents; 
            }
 
            if (displayTags && RenderUplevel) {

                // Put ourselves in the array
                RegisterValidatorDeclaration(); 

                // Set extra uplevel styles 
                if (display == ValidatorDisplay.None 
                    || (!shouldBeVisible && display == ValidatorDisplay.Dynamic)) {
                    Style["display"] = "none"; 
                }
                else if (!shouldBeVisible) {
                    Debug.Assert(display == ValidatorDisplay.Static, "Unknown Display Type");
                    Style["visibility"] = "hidden"; 
                }
            } 
 
            // Display it
            if (displayTags) { 
                RenderBeginTag(writer);
            }
            if (displayContents) {
                if (Text.Trim().Length > 0) { 
                    RenderContents(writer);
                } 
                else if (HasRenderingData()) { 
                    base.RenderContents(writer);
                } 
                else {
                    writer.Write(ErrorMessage);
                }
            } 
            else if (!RenderUplevel && display == ValidatorDisplay.Static) {
                // For downlevel in static mode, render a space so that table cells do not render as empty 
                writer.Write(" "); 
            }
            if (displayTags) { 
                RenderEndTag(writer);
            }
        }
 

        ///  
        /// Evaluates validity and updates the  property. 
        /// 
        public void Validate() { 
            IsValid = true;
            if (!Visible || !Enabled) {
                return;
            } 
            propertiesChecked = false;
            if (!PropertiesValid) { 
                return; 
            }
            IsValid = EvaluateIsValid(); 
            Debug.Trace("BaseValidator.Validate", "id:" + ID + ", evaluateIsValid = " + IsValid.ToString());
            if (!IsValid) {
                Page page = Page;
                if (page != null && SetFocusOnError) { 
                    Page.SetValidatorInvalidControlFocus(ControlToValidate);
                } 
            } 
        }
    } 
}


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK