ASP.NET validation works in mysterious ways especially when you want to validate a group of controls on the page. In this article we are going to dig deep into the ValidationGroup property and see how to validate a group of controls.
Introduction:
ASP.NET validation
works in mysterious ways especially when you want to validate a group of
controls on the page. In this article we are going to dig deep into the
ValidationGroup property and see how to validate a group of controls.
Implementation:
Consider that you
have two TextBoxes on the page. Each TextBox has its own validator control.
Here is the code:
<div class="blue">
<asp:TextBox ID="txtBlue"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvBlue" runat="server"
ControlToValidate="txtBlue" ErrorMessage="Blue TextBox is
required" />
</div>
<div class="yellow">
<asp:TextBox
ID="txtYellow" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator
ID="rfvYellow" runat="server"
ControlToValidate="txtYellow" ErrorMessage="Yellow TextBox is
required" />
</div>
I also have two
buttons on the form.
<asp:Button ID="btn_Blue"
runat="server" Text="Validation BLUE"
OnClick="Validate_Blue" />
<asp:Button ID="btn_Yellow"
runat="server" Text="Validation YELLOW"
OnClick="Validate_Yellow" />
btn_Blue is used to
validate the "txtBlue" TextBox and btn_Yellow is used to validate the
"txtYellow" TextBox. If you click on any of the TextBox both the
validators will be fired. You will see the following output:
As, you can see both
the validators on the page are fired even though we only wanted to validate the
txtBlue (Blue TextBox). In order to only fire the validation on particular
controls we need to introduce the ValidationGroup property. Here it goes:
<div class="blue">
<asp:TextBox ID="txtBlue"
ValidationGroup="blue"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator
ID="rfvBlue" ValidationGroup="blue" runat="server"
ControlToValidate="txtBlue" ErrorMessage="Blue TextBox is
required" />
</div>
<div class="yellow">
<asp:TextBox
ID="txtYellow" ValidationGroup="yellow"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator
ID="rfvYellow" ValidationGroup="yellow"
runat="server" ControlToValidate="txtYellow"
ErrorMessage="Yellow TextBox is required" />
</div>
<br />
<br />
<asp:Button ID="btn_Blue"
runat="server" ValidationGroup="blue" Text="Validation
BLUE" OnClick="Validate_Blue" />
<br />
<asp:Button ID="btn_Yellow"
runat="server" ValidationGroup="yellow"
Text="Validation YELLOW" OnClick="Validate_Yellow"
/>
</div>
As, you can see in
the above code the ValidationGroup property is set on the TextBox controls,
Validation controls and the Button control. Now, if I click the btn_Blue button
it will only validate the txtBlue control (Blue TextBox).
But hey! Why do we
have the ValidationGroup property on the TextBox controls. It should only be on
the Validation controls since they are fired and they know which control to
validate using the "ControlToValidate" property. So, let's remove the
ValidationGroup property from the TextBox controls.
Here is the code:
<div>
<div class="blue">
<asp:TextBox ID="txtBlue"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator
ID="rfvBlue" ValidationGroup="blue" runat="server"
ControlToValidate="txtBlue" ErrorMessage="Blue TextBox is
required" />
</div>
<div class="yellow">
<asp:TextBox
ID="txtYellow" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator
ID="rfvYellow" ValidationGroup="yellow"
runat="server" ControlToValidate="txtYellow"
ErrorMessage="Yellow TextBox is required" />
</div>
<br />
<br />
<asp:Button ID="btn_Blue"
runat="server" ValidationGroup="blue" Text="Validation
BLUE" OnClick="Validate_Blue" />
<br />
<asp:Button ID="btn_Yellow"
runat="server" ValidationGroup="yellow"
Text="Validation YELLOW" OnClick="Validate_Yellow"
/>
</div>
Refresh the page and
you will notice that it still works. This is because the Button click will fire
the matching validation group which will be the validator control. And the validator
control will fire the Validate method on the control which is represented by
the "ControlToValidate" property.
If you are using
user controls and want to group the validation depending on the user controls
then you will have to take a different route. One of the ways is to just hard
code the ValidationGroup for each control inside the user control. I think that
is a bad solution when you want to validate the user control as a single unit.
Here is one approach which dynamically assigns the ValidationGroup to the
controls within the user control.
Check out the class
diagram below:
Basically, the
BaseUserControl exposes a ValidationGroup property which can be used by the
derived controls on the page to set up the ValidationGroup. After that the
Button on the page is assigned the same ValidationGroup which was assigned to
the user control.
Now, when the Button
is clicked only the group matching the ValidationGroup of the Button gets
validated.
Here is the
implementation of the BaseUserControl clasS:
public class BaseUserControl : UserControl
{
public BaseUserControl()
{
// automatically register the event
this.Load += new
EventHandler(BaseUserControl_Load);
}
void BaseUserControl_Load(object
sender, EventArgs e)
{
// something!
AssignValidationGroupToControls();
}
// assign the validation group to the
controls
protected void AssignValidationGroupToControls()
{
// get the validation control from
this control and assign the validation group
foreach (Control control in
this.Controls)
{
PropertyInfo property =
control.GetType().GetProperty("ValidationGroup");
if (property == null) continue;
property.SetValue(control,
ValidationGroup, null);
}
}
public string ValidationGroup
{
get { return
(string)ViewState["ValidationGroup"]; }
set {
ViewState["ValidationGroup"] = value; }
}
}
The
AssignValidationGroupToControls simply assigns the ValidationGroup as set in
the ASPX page to the controls that have the ValidationGroup property. Here is
the usage on the page:
<uc1:BlueTextBox
ID="blueControl" runat="server"
ValidationGroup="blue" />
<asp:Button
ID="btn_Blue" runat="server"
ValidationGroup="blue" Text="Validation BLUE"
OnClick="Validate_Blue" />
<uc2:YellowTextBox
ID="yellowControl" runat="server"
ValidationGroup="yellow" />
<asp:Button ID="btn_Yellow"
runat="server" ValidationGroup="yellow"
Text="Validation YELLOW" OnClick="Validate_Yellow"
/>
Conclusion: