Have
you ever wondered how you go about validating a custom composite web
control? Normally, with ASP.NET server controls, you have:
<asp:TextBox ID="PhoneTextBox" runat="server" />
<asp:RequiredFieldValidator ID="PhoneRequiredFieldValidator"
runat="server" ControlToValidate="PhoneTextBox" Display="Dynamic"
ErrorMessage="Please enter a phone number" />
But with a custom composite web control, say one which
includes a label, a text box, and a required field validator, any
validators that refer to your control will not know how to validate the
data.
Say we have the following custom composite web control:
public class LabelledTextBox : CompositeControl
{
private Label _nameLabel = new Label();
private TextBox _nameTextBox = new TextBox();
private RequiredFieldValidator _nameRequiredFieldValidator = new RequiredFieldValidator();
public LabelledTextBox()
{
_nameLabel.ID = "NameLabel";
_nameLabel.Text = "My Label: ";
_nameTextBox.ID = "NameTextBox";
_nameRequiredFieldValidator.ID = "NameRequiredFieldValidator";
_nameRequiredFieldValidator.ControlToValidate = _nameTextBox.ID;
}
protected override void CreateChildControls()
{
Controls.Add(_nameLabel);
Controls.Add(_nameTextBox);
Controls.Add(_nameRequiredFieldValidator);
base.CreateChildControls();
}
public string Text
{
get { return _nameTextBox.Text; }
set { _nameTextBox.Text = value; }
}
}
The RequiredFieldValidator inside the composite control
can validate the text box just fine, as it knows about it. However, if
you want to validate that the text box has, say, an integer between 1
and 100, by adding a RangeValidator to the markup, the validation will
not work. You will get an error stating that the LabelledTextBox
control cannot be validated. So, after some failed google attempts to
find out how to solve this problem, my coworker Bryan Smith recalled
that in Fritz Onion's book, Essential ASP.NET With Examples in C#,
Fritz mentioned the ValidationProperty attribute that could be used to
specify which property of the composite control should be validated.
So if we just add that attribute to the custom composite control class, we can then validate it:
[ValidationProperty("Text")]
public class LabelledTextBox : CompositeControl
So now when we have the following in our markup, it will validate the text box just fine:
<asp:LabelledTextBox ID="AgeLabelledTextBox" runat="server"/>
<asp:RangeValidator ID="AgeValidator" runat="server" ControlToValidate="AgeLabelledTextBox" Display="Dynamic"
ErrorMessage="Please enter an age between 1 and 100" Type="Integer"MinimumValue="1" MaximumValue="100" />
Thanks to the ValidationProperty, the framebwork now
knows that the Text property of the custom composite control should be
checked to make sure the value is between 1 and 100.
But there is a gotcha here. The client side validation
will appear to work just fine with the above scenario. But if you have
two text boxes within the same composite control,only the first one
will be validated. The reason for this, as Bryan and I discovered, is
that the validation javascript actually iterates through the child
nodes of the composite control(rendered as a span) until it sees a
control that has a value property. It then validates that control and
that control only.
So again, always validate your input at both client AND server sides.
Read the complete post at http://www.dotnetmafia.com/Home/tabid/37/EntryID/13/Default.aspx