//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Web; using System.Web.UI; using System.Web.UI.Design.WebControls; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Diagnostics; using WebCntrls = System.Web.UI.WebControls; using System.Security.Permissions; namespace System.Web.UI.MobileControls { /* * Mobile BaseValidator class. * The BaseValidator class provides a core implementation common to all * specific validator controls. * * Copyright (c) 2000 Microsoft Corporation */ /// [ DataBindingHandler("System.Web.UI.Design.TextDataBindingHandler, " + AssemblyRef.SystemDesign), DefaultProperty("ErrorMessage"), Designer(typeof(System.Web.UI.Design.MobileControls.BaseValidatorDesigner)), DesignerAdapter(typeof(System.Web.UI.Design.MobileControls.Adapters.DesignerValidatorAdapter)), ] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] public abstract class BaseValidator : TextControl, IValidator { private WebCntrls.BaseValidator _webBaseValidator; private bool _isValid = true; /// protected BaseValidator() { _webBaseValidator = CreateWebValidator(); if (_webBaseValidator == null) { // Create a default web base validator, mainly for storing // property values. _webBaseValidator = new DefaultWebValidator(); } Controls.Add(_webBaseValidator); // Currently by default we render error message in a dynamic way. _webBaseValidator.Display = ValidatorDisplay.Dynamic; } /// public override int VisibleWeight { get { return 0; // validators are not generally visible } } /// /// /// /// Virtual method for subclass to create its own aggregated /// web validator. The web validator is for getting and /// setting of the common properties of web base validator. /// /// protected virtual WebCntrls.BaseValidator CreateWebValidator() { return null; } protected override Style CreateStyle() { Style style = new Style(); style.StyleReference = Constants.ErrorStyle; return style; } //////////////////////////////////////////////////////////////////////// // Mimic the properties exposed in the original BaseValidator. //////////////////////////////////////////////////////////////////////// /// [ Browsable(false), DefaultValue(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public bool IsValid { // Not getting and setting to the corresponding property in the // WebForm Base Validator is to differentiate the valid state for // Mobile Validator as Mobile Page can have multiple forms where the // Mobile Validator is invalid only when the same form is post back. // // Also, this property shouldn't be persisted in ViewState[] because // error message will show up when the form that contains the // validator is revisited again and the validator's state should // be reset to true as default. Same implementation is done in // WebForm BaseValidator. // e.g. Form1 contains a Validator and a TextBox and a Command to // Form2 which contains a ValidationSummary. After a user enters // an invalid value and click Command, ValidationSummary will // list the error message and provide a link back to Form1. // If IsValid property is persisted via ViewState[], Form1 will show // error message since IsValid is false and persisted, while the // expected behavior is the validator's state on Form1 is reset // to true so no error message will be shown. get { return _isValid; } set { _isValid = value; } } /// [ Bindable(true), DefaultValue(""), MobileCategory(SR.Category_Appearance), MobileSysDescription(SR.BaseValidator_ErrorMessage) ] public String ErrorMessage { get { return _webBaseValidator.ErrorMessage; } set { _webBaseValidator.ErrorMessage = value; } } /// [ Bindable(false), DefaultValue(""), MobileCategory(SR.Category_Behavior), MobileSysDescription(SR.BaseValidator_ControlToValidate), TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.ValidatedMobileControlConverter)) ] public String ControlToValidate { get { return _webBaseValidator.ControlToValidate; } set { _webBaseValidator.ControlToValidate = value; } } /// [ Bindable(true), DefaultValue(ValidatorDisplay.Dynamic), MobileCategory(SR.Category_Appearance), MobileSysDescription(SR.BaseValidator_Display) ] public ValidatorDisplay Display { get { return _webBaseValidator.Display; } set { _webBaseValidator.Display = value; } } // Designer needs to know the correct default value in order to persist it correctly. /// [ DefaultValue(Constants.ErrorStyle) ] public override String StyleReference { get { return base.StyleReference; } set { base.StyleReference = value; } } /// protected override void OnInit(EventArgs e) { // Add itself to the Validator list so the Validate() function // will be called to validate control Page.Validators.Add(this); base.OnInit(e); } /// protected override void OnPreRender(EventArgs e) { if(this.Form == MobilePage.ActiveForm) { bool isValid = ControlPropertiesValid(); Debug.Assert(isValid, "Exception should have been thrown instead of returning false!"); } base.OnPreRender(e); } // Common code shared by other validators in the same assembly internal bool EvaluateIsValidInternal() { // At this point all validator's related info should have been // redirected to the aggregated Web Validator. Simply apply the // validation logic in the Web Validator to determine if the // checked control is valid. String idBuffer; try { _webBaseValidator.Validate(); } catch { // Swap IDs with aggregate validator so that is Validate() throws // a meaningful ID is included in the exception message. idBuffer = ID; ID = _webBaseValidator.ID; _webBaseValidator.ID = idBuffer; try { _webBaseValidator.Validate(); } finally { idBuffer = ID; ID = _webBaseValidator.ID; _webBaseValidator.ID = idBuffer; } // If the exception does not repro with swapped ID, just re-throw it. throw; } return _webBaseValidator.IsValid; } // Subclass should provide its own logic for validation /// protected abstract bool EvaluateIsValid(); /// public void Validate() { if (!Visible) { IsValid = true; return; } // See if we are in an invisible container Control parent = Parent; while (parent != null) { if (!parent.Visible) { IsValid = true; return; } parent = parent.Parent; } IsValid = EvaluateIsValid(); } ///////////////////////////////////////////////////////////////////// // Helper functions adopted from WebForms base validator ///////////////////////////////////////////////////////////////////// /// protected virtual bool ControlPropertiesValid() { // Check for blank control to validate String controlToValidate = ControlToValidate; if (controlToValidate.Length == 0) { throw new ArgumentException(SR.GetString( SR.BaseValidator_ControlToValidateBlank, ID)); } // Check that the property points to a valid control. // Will throw an exception if not found CheckControlValidationProperty(controlToValidate, "ControlToValidate"); return true; } /// protected void CheckControlValidationProperty(String name, String propertyName) { // Get the control using the relative name Control control = NamingContainer.FindControl(name); if (control == null) { throw new ArgumentException(SR.GetString( SR.BaseValidator_ControlNotFound, name, propertyName, ID)); } // Get its validation property PropertyDescriptor prop = WebCntrls.BaseValidator.GetValidationProperty(control); if (prop == null) { throw new ArgumentException(SR.GetString( SR.BaseValidator_BadControlType, name, propertyName, ID)); } } private class DefaultWebValidator : WebCntrls.BaseValidator { protected override bool EvaluateIsValid() { Debug.Assert(false, "Should never be called."); return true; } } } }