Validation Controls
|
This section documents ASP.NET Web Forms on .NET Framework 4.8.1, the last and permanent version of Web Forms — the page life cycle and postback model, ViewState and control state, server controls, validation controls, master pages and themes, data-bound controls, and the provider-based security model — as described by the official documentation at Microsoft Learn and the ASP.NET previous-versions archive, which are the reference these pages are written and verified against. Web Forms receives security fixes only and has no forward path onto modern .NET (.NET Framework 4.8.1 is Microsoft’s last version of .NET Framework; Web Forms itself never shipped on .NET Core/.NET 5+). It remains supported for existing applications running on Windows but is not recommended for new development — see Choosing an ASP.NET Framework and Migrating to Modern ASP.NET for what that means in practice. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Web Forms validation controls declaratively bind a rule to an input control and run that rule both in the browser (via injected JavaScript) and again on the server (because client-side checks can always be bypassed), without hand-writing either half.
The built-in validator controls
| Control | Checks |
|---|---|
|
The associated control has a non-empty, non- |
|
The value falls between |
|
Compares against a fixed value, another control’s value ( |
|
The value matches a |
|
Arbitrary logic via a server |
|
Aggregates every failed validator’s |
<asp:TextBox ID="EmailBox" runat="server" />
<asp:RequiredFieldValidator ID="EmailRequired" runat="server"
ControlToValidate="EmailBox" ErrorMessage="Email is required." Display="Dynamic" />
<asp:RegularExpressionValidator ID="EmailFormat" runat="server"
ControlToValidate="EmailBox" ErrorMessage="Enter a valid email address."
ValidationExpression="^[^@\s]+@[^@\s]+\.[^@\s]+$" Display="Dynamic" />
<asp:TextBox ID="AgeBox" runat="server" />
<asp:RangeValidator ID="AgeRange" runat="server" ControlToValidate="AgeBox"
Type="Integer" MinimumValue="0" MaximumValue="120" ErrorMessage="Age must be 0-120." />
<asp:TextBox ID="PasswordBox" runat="server" TextMode="Password" />
<asp:TextBox ID="ConfirmBox" runat="server" TextMode="Password" />
<asp:CompareValidator ID="PasswordsMatch" runat="server"
ControlToValidate="ConfirmBox" ControlToCompare="PasswordBox"
ErrorMessage="Passwords do not match." />
<asp:ValidationSummary ID="Summary" runat="server" HeaderText="Please fix the following:" />
CustomValidator covers anything the built-in validators cannot express, such as a rule needing a database
lookup:
<asp:CustomValidator ID="UsernameAvailable" runat="server"
ControlToValidate="UsernameBox" OnServerValidate="UsernameAvailable_ServerValidate"
ErrorMessage="That username is already taken." />
protected void UsernameAvailable_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = !_userRepository.UsernameExists(args.Value);
}
ValidationGroup
A page with multiple independent forms (e.g. a login box and a newsletter sign-up box on the same page) uses
ValidationGroup to scope which validators fire for which submit button, so submitting one form does not
trigger validation errors from the other:
<asp:TextBox ID="LoginUserBox" runat="server" ValidationGroup="Login" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="LoginUserBox"
ValidationGroup="Login" ErrorMessage="Username required." />
<asp:Button ID="LoginButton" runat="server" Text="Log in" ValidationGroup="Login" />
<asp:TextBox ID="NewsletterEmailBox" runat="server" ValidationGroup="Newsletter" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="NewsletterEmailBox"
ValidationGroup="Newsletter" ErrorMessage="Email required." />
<asp:Button ID="SubscribeButton" runat="server" Text="Subscribe" ValidationGroup="Newsletter" />
Page.IsValid and Validate()
Server-side code must always check Page.IsValid before acting on submitted data — client-side validation is
a UX convenience, not a security boundary, and can be bypassed entirely (disabled JavaScript, a hand-crafted
POST):
protected void SaveButton_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
{
return; // validators already populated their error messages; nothing else to do
}
_customerService.Save(EmailBox.Text, int.Parse(AgeBox.Text));
}
Page.IsValid reflects the last call to Page.Validate(), which ASP.NET calls automatically for any control
whose CausesValidation is true (the default for Button/LinkButton/ImageButton) when it causes a
postback. Calling Page.Validate("GroupName") explicitly (rather than relying on automatic validation) is
needed when validating a specific group outside the normal button-click flow.
Server/client duality
Each validator renders both the markup ASP.NET needs to evaluate it server-side and, when the
MS_AJAX_…/WebResource.axd-served client validation script is present (automatic unless explicitly
disabled), a matching client-side check that runs on submit and toggles the control’s visibility/CSS class
without a round trip. The server-side check always re-runs regardless of what the client already reported — this is why removing or working around the client script never bypasses server enforcement, only the instant
feedback.
Unobtrusive validation (4.5) and its jQuery dependency
Starting with ASP.NET 4.5, ValidationSettings:UnobtrusiveValidationMode (in web.config, or
Page.UnobtrusiveValidationMode) switches client-side validation from inline onsubmit/onclick script
blocks to data-val-* HTML5 attributes read by a small unobtrusive-validation script, which in turn depends
on jQuery being present on the page:
<appSettings>
<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />
</appSettings>
<!-- rendered output changes shape but not semantics -->
<input name="EmailBox" type="text" data-val="true"
data-val-required="Email is required."
data-val-regex="Enter a valid email address."
data-val-regex-pattern="^[^@amp;\s]+@[^@amp;\s]+\.[^@amp;\s]+$" />
This mode requires jQuery (and the WebForms.js/MicrosoftAjaxWebForms.js unobtrusive-validation shim) to
be referenced on the page — a ScriptManager typically pulls these in automatically (see
AJAX and Client-Side Integration); without jQuery loaded,
client-side validation silently does not run (server-side validation is unaffected either way).
CausesValidation
Any control that submits the page can opt out of triggering validation with CausesValidation="false" — essential for "Cancel" buttons, which should post back (to abandon edits and navigate away) without being
blocked by unrelated validators on the same form:
<asp:Button ID="CancelButton" runat="server" Text="Cancel"
CausesValidation="false" OnClick="CancelButton_Click" />