2 // System.Web.UI.WebControls.BaseValidator
5 // Chris Toshok (toshok@novell.com)
7 // (C) 2005 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Web.Configuration;
30 using System.ComponentModel;
32 using System.Reflection;
33 using System.Collections;
34 using System.Security.Permissions;
36 namespace System.Web.UI.WebControls {
39 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42 [DefaultProperty("ErrorMessage")]
43 [Designer("System.Web.UI.Design.WebControls.BaseValidatorDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 public abstract class BaseValidator : Label, IValidator
50 protected BaseValidator ()
53 this.ForeColor = Color.Red;
59 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
61 [EditorBrowsable(EditorBrowsableState.Never)]
62 public override string AssociatedControlID {
64 return base.AssociatedControlID;
67 base.AssociatedControlID = value;
74 public virtual string ValidationGroup {
75 get { return ViewState.GetString ("ValidationGroup", String.Empty); }
76 set { ViewState["ValidationGroup"] = value; }
80 [DefaultValue (false)]
81 public bool SetFocusOnError {
82 get { return ViewState.GetBool ("SetFocusOnError", false); }
83 set { ViewState["SetFocusOnError"] = value; }
86 /* listed in corcompare */
87 [MonoTODO("Why override?")]
88 [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
90 public override string Text
92 get { return base.Text; }
93 set { base.Text = value; }
98 [IDReferenceProperty (typeof (Control))]
101 [TypeConverter(typeof(System.Web.UI.WebControls.ValidatedControlConverter))]
103 [WebSysDescription ("")]
104 [WebCategory ("Behavior")]
105 public string ControlToValidate {
106 get { return ViewState.GetString ("ControlToValidate", String.Empty); }
107 set { ViewState ["ControlToValidate"] = value; }
116 [DefaultValue(ValidatorDisplay.Static)]
117 [WebSysDescription ("")]
118 [WebCategory ("Appearance")]
119 public ValidatorDisplay Display {
120 get { return (ValidatorDisplay)ViewState.GetInt ("Display", (int)ValidatorDisplay.Static); }
121 set { ViewState ["Display"] = (int)value; }
128 [WebSysDescription ("")]
129 [WebCategory ("Behavior")]
130 public bool EnableClientScript {
131 get { return ViewState.GetBool ("EnableClientScript", true); }
132 set { ViewState ["EnableClientScript"] = value; }
135 public override bool Enabled {
136 get { return ViewState.GetBool ("BaseValidatorEnabled", true); }
137 set { ViewState ["BaseValidatorEnabled"] = value; }
147 [WebSysDescription ("")]
148 [WebCategory ("Appearance")]
154 string ErrorMessage {
155 get { return ViewState.GetString ("ErrorMessage", String.Empty); }
156 set { ViewState ["ErrorMessage"] = value; }
159 [DefaultValue(typeof (Color), "Red")]
160 public override Color ForeColor {
161 get { return forecolor; }
164 base.ForeColor = value;
173 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
174 [WebSysDescription ("")]
175 [WebCategory ("Misc")]
182 get { return valid; }
183 set { valid = value; }
186 protected bool PropertiesValid {
188 Control control = NamingContainer.FindControl (ControlToValidate);
196 protected bool RenderUplevel {
197 get { return render_uplevel; }
200 internal bool GetRenderUplevel ()
202 return render_uplevel;
205 protected override void AddAttributesToRender (HtmlTextWriter writer)
207 /* if we're rendering uplevel, add our attributes */
208 if (render_uplevel) {
209 /* force an ID here if we weren't assigned one */
211 writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
213 if (ControlToValidate != String.Empty)
215 RegisterExpandoAttribute (ClientID, "controltovalidate", GetControlRenderID (ControlToValidate));
217 writer.AddAttribute ("controltovalidate", GetControlRenderID (ControlToValidate));
220 if (ErrorMessage != String.Empty)
222 RegisterExpandoAttribute (ClientID, "errormessage", ErrorMessage, true);
224 writer.AddAttribute ("errormessage", ErrorMessage);
226 if (Text != String.Empty)
227 writer.AddAttribute ("text", Text);
231 if (ValidationGroup != String.Empty)
232 RegisterExpandoAttribute (ClientID, "validationGroup", ValidationGroup, true);
235 RegisterExpandoAttribute (ClientID, "focusOnError", "t");
239 RegisterExpandoAttribute (ClientID, "enabled", "False");
241 writer.AddAttribute ("enabled", "false", false);
245 if (Enabled && !IsValid) {
246 RegisterExpandoAttribute (ClientID, "isvalid", "False");
249 writer.AddAttribute ("isvalid", "false", false);
253 if (Display == ValidatorDisplay.Static)
254 writer.AddStyleAttribute ("visibility", "hidden");
256 writer.AddStyleAttribute ("display", "none");
259 if (Display != ValidatorDisplay.Static)
261 RegisterExpandoAttribute (ClientID, "display", Display.ToString ());
263 writer.AddAttribute ("display", Display.ToString());
267 base.AddAttributesToRender (writer);
271 internal void RegisterExpandoAttribute (string controlId, string attributeName, string attributeValue) {
272 RegisterExpandoAttribute (controlId, attributeName, attributeValue, false);
275 internal void RegisterExpandoAttribute (string controlId, string attributeName, string attributeValue, bool encode) {
276 if (Page.ScriptManager != null)
277 Page.ScriptManager.RegisterExpandoAttributeExternal (this, controlId, attributeName, attributeValue, encode);
279 Page.ClientScript.RegisterExpandoAttribute (controlId, attributeName, attributeValue, encode);
283 protected void CheckControlValidationProperty (string name, string propertyName)
285 Control control = NamingContainer.FindControl (name);
286 PropertyDescriptor prop = null;
289 throw new HttpException (String.Format ("Unable to find control id '{0}'.", name));
291 prop = BaseValidator.GetValidationProperty (control);
293 throw new HttpException (String.Format ("Unable to find ValidationProperty attribute '{0}' on control '{1}'", propertyName, name));
296 protected virtual bool ControlPropertiesValid ()
298 if (ControlToValidate.Length == 0) {
299 throw new HttpException (String.Format ("ControlToValidate property of '{0}' cannot be blank.", ID));
302 CheckControlValidationProperty (ControlToValidate, "");
307 protected virtual bool DetermineRenderUplevel ()
309 if (!EnableClientScript)
312 if (HttpContext.Current == null)
316 /* From someplace on the web: "JavaScript 1.2
317 * and later (also known as ECMAScript) has
318 * built-in support for regular
320 ((Page.Request.Browser.EcmaScriptVersion.Major == 1
321 && Page.Request.Browser.EcmaScriptVersion.Minor >= 2)
322 || (Page.Request.Browser.EcmaScriptVersion.Major > 1))
324 /* document.getElementById, .getAttribute,
325 * etc, are all DOM level 1. I don't think we
326 * use anything in level 2.. */
327 && Page.Request.Browser.W3CDomVersion.Major >= 1);
329 return UplevelHelper.IsUplevel (
330 System.Web.Configuration.HttpCapabilitiesBase.GetUserAgentForDetection (HttpContext.Current.Request));
334 protected abstract bool EvaluateIsValid ();
336 protected string GetControlRenderID (string name)
338 Control control = NamingContainer.FindControl (name);
342 return control.ClientID;
345 protected string GetControlValidationValue (string name)
347 Control control = NamingContainer.FindControl (name);
352 PropertyDescriptor prop = BaseValidator.GetValidationProperty (control);
356 object o = prop.GetValue (control);
362 return ((ListItem) o).Value;
364 return o.ToString ();
367 public static PropertyDescriptor GetValidationProperty (object o)
369 PropertyDescriptorCollection props;
370 System.ComponentModel.AttributeCollection col;
372 props = TypeDescriptor.GetProperties (o);
373 col = TypeDescriptor.GetAttributes (o);
375 foreach (Attribute at in col) {
376 ValidationPropertyAttribute vpa = at as ValidationPropertyAttribute;
377 if (vpa != null && vpa.Name != null)
378 return props[vpa.Name];
389 override void OnInit (EventArgs e)
391 /* according to an msdn article, this is done here */
393 Page.Validators.Add (this);
396 Page.GetValidators (ValidationGroup).Add (this);
402 bool pre_render_called = false;
409 override void OnPreRender (EventArgs e)
411 base.OnPreRender (e);
413 pre_render_called = true;
415 ControlPropertiesValid ();
417 render_uplevel = DetermineRenderUplevel ();
418 if (render_uplevel) {
419 RegisterValidatorCommonScript ();
428 override void OnUnload (EventArgs e)
430 /* according to an msdn article, this is done here */
432 Page.Validators.Remove (this);
435 if (ValidationGroup != "")
436 Page.GetValidators (ValidationGroup).Remove (this);
443 protected void RegisterValidatorCommonScript ()
446 if (Page.ScriptManager != null) {
447 Page.ScriptManager.RegisterClientScriptResourceExternal (this, typeof (BaseValidator), "WebUIValidation_2.0.js");
448 Page.ScriptManager.RegisterClientScriptBlockExternal (this, typeof (BaseValidator), "ValidationInitializeScript", Page.ValidationInitializeScript, true);
449 Page.ScriptManager.RegisterOnSubmitStatementExternal (this, typeof (BaseValidator), "ValidationOnSubmitStatement", Page.ValidationOnSubmitStatement);
450 Page.ScriptManager.RegisterStartupScriptExternal (this, typeof (BaseValidator), "ValidationStartupScript", Page.ValidationStartupScript, true);
454 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof (BaseValidator), "Mono-System.Web-ValidationClientScriptBlock"))
456 Page.ClientScript.RegisterClientScriptInclude (typeof (BaseValidator), "Mono-System.Web-ValidationClientScriptBlock",
457 Page.ClientScript.GetWebResourceUrl (typeof (BaseValidator),
459 "WebUIValidation_2.0.js"));
460 Page.ClientScript.RegisterClientScriptBlock (typeof (BaseValidator), "Mono-System.Web-ValidationClientScriptBlock.Initialize", Page.ValidationInitializeScript, true);
461 Page.ClientScript.RegisterOnSubmitStatement (typeof (BaseValidator), "Mono-System.Web-ValidationOnSubmitStatement", Page.ValidationOnSubmitStatement);
462 Page.ClientScript.RegisterStartupScript (typeof (BaseValidator), "Mono-System.Web-ValidationStartupScript", Page.ValidationStartupScript, true);
464 "WebUIValidation.js"));
466 Page.ClientScript.RegisterOnSubmitStatement ("Mono-System.Web-ValidationOnSubmitStatement",
467 "if (!ValidatorOnSubmit()) return false;");
468 Page.ClientScript.RegisterStartupScript ("Mono-System.Web-ValidationStartupScript",
469 "<script language=\"JavaScript\">\n" +
471 "var Page_ValidationActive = false;\n" +
472 "ValidatorOnLoad();\n" +
474 "function ValidatorOnSubmit() {\n" +
475 " if (Page_ValidationActive) {\n" +
476 " if (!ValidatorCommonOnSubmit())\n" +
477 " return Page_ClientValidate ();\n" +
487 protected virtual void RegisterValidatorDeclaration ()
490 if (Page.ScriptManager != null) {
491 Page.ScriptManager.RegisterArrayDeclarationExternal (this, "Page_Validators", String.Concat ("document.getElementById ('", ClientID, "')"));
492 Page.ScriptManager.RegisterStartupScriptExternal (this, typeof (BaseValidator), ClientID + "DisposeScript",
494 document.getElementById('" + ClientID + @"').dispose = function() {
495 Array.remove(Page_Validators, document.getElementById('" + ClientID + @"'));
501 Page.ClientScript.RegisterArrayDeclaration ("Page_Validators",
502 String.Concat ("document.getElementById ('", ClientID, "')"));
510 override void Render (HtmlTextWriter writer)
513 if (!Enabled && !EnableClientScript)
516 if (render_uplevel) {
517 /* according to an msdn article, this is done here */
518 RegisterValidatorDeclaration ();
521 bool render_tags = false;
522 bool render_text = false;
523 bool render_nbsp = false;
526 if (!pre_render_called) {
530 else if (render_uplevel) {
533 render_text = Display != ValidatorDisplay.None;
535 if (Display != ValidatorDisplay.None)
536 render_text = !v || Display == ValidatorDisplay.Dynamic;
540 if (Display != ValidatorDisplay.None) {
543 render_nbsp = v && Display == ValidatorDisplay.Static;
548 AddAttributesToRender (writer);
549 writer.RenderBeginTag (HtmlTextWriterTag.Span);
552 if (render_text || render_nbsp) {
567 writer.RenderEndTag ();
571 /* the docs say "public sealed" here */
579 if (Enabled && Visible)
580 IsValid = ControlPropertiesValid () && EvaluateIsValid ();