65.9K
CodeProject is changing. Read more.
Home

Rule Based Validation for ASP.NET

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (26 votes)

Apr 17, 2012

CPOL

7 min read

viewsIcon

52849

downloadIcon

1329

Enhanced web page validation based on multiple rules at client and server side.

Introduction

A modern and user friendly web application will recognize invalid user input as early as possible and will signal such conditions to the user. For the ASP.NET Framework there exist various controls for the validation of user input. These validators spring into action in the browser on the user's computer and thus prevent time and resource intensive requests to the web server.

In real world scenarios these validators will only suffice for simple applications. Very quickly a point is reached, where the development of a specialized validator becomes unavoidable. Doing so requires to implement the necessary validation functionality both in C# resp. VB.NET for the server side as well as in JavaScript for the client side. Both implementations reflect the same validation logic. In general, the JavaScript Code will be generated by C#/VB.NET code, which can make maintenance and documentation of such validators complicated.

The component introduced here extends the ASP.NET validators by a simple rule framework, covering the following functionality:

  • Validation of checkboxes and radio buttons
  • Atomic validation of multiple input values
  • Validation of input according to logical conditions
  • Variable definition of validation rules
  • Incorporation of the standard ASP.NET validators
  • No additional JavaScript code required

Realization of this component was inspired by the excellent article Multiple Fields Validator - An ASP.NET Validation Control by Adam Tibi.

Custom Control Validation

The validators contained in ASP.NET can only be applied to controls which have been marked with the ValidationProperty. The validation of user input can require to ensure validity depending on the state of checkboxes and radio buttons. Unfortunately, the corresponding .NET controls are not validatable by default and have to be extended by own derivations to support this. For this purpose, the accompanying library contains the controls ValidatableRadioButton and ValidatableCheckBox:

// ------------------------------------------------------------------------
[ValidationProperty( "ValidationValue" )]
public class ValidatableCheckBox : CheckBox
{

  // ----------------------------------------------------------------------
  public string ValidationValue
  {
    get { return ( Checked ? bool.TrueString : bool.FalseString ); }
  } // ValidationValue

} // class ValidatableCheckBox

Note: These extensions are designed for rule based validation and cannot be used in conjunction with the standard ASP.NET validators.

Solution Approach

The graphical overview shows the workflow of the rule validation. Validation is triggered by the Validation Trigger - which is most commonly a button. According to the validator property EnableClientScript it is determined whether client side validation will occur. This value is set to true by default and should only be changed in exceptional situations.

In Evaluate Rules follows the client side checking of the rules defined in the validator. With JavaScript the input values will be checked against the rules of the validator. According to the validation type (prescription/prohibition) it is determined whether validation succeeded or failed.

In case validation failed, a client side generated error message is displayed and will lead to the abortion of the user request.

With succeeding client side validation, the user request is sent to the web server, where Evaluate Rules will perform the same validation sequence checking in C#/VB.NET. Failing to pass this, a corresponding error message will be displayed in the web client.

In case the server side validation succeeds as well, further processing of the request is guaranteed to operate on valid input data.

Each rule is described by the following properties:

  • Operation: The calculation logic of the rule
  • Scope: The controls to be considered by the rule
    The controls are being referenced in form of a comma separated list of IDs
  • Source: The source of the data to validate
    The rule applies to the value of the control (default) or its selection (ValidatableRadioButton or ValidatableCheckBox)
  • CompareValue: The value to compare in the rule
    This value will be compared with the content of the control (default=empty text)
  • CompareCount: The count to validate in the rule
    The count only applies to certain rule operations (see further below)

Invalid control references in Scope or an invalid count in CompareCount will be detected by the system and result in a runtime exception.

Rule Operation

The possible rule operations are defined in the enumeration RuleOperation:

Operation Description Scope Target Scope Count Value Condition Option Condition
AtLeastOne At least one is matching (OR) Validatable Control 2+ CompareValue Is selected
None None is matching (NOR) Validatable Control 2+ CompareValue Is selected
OneOfTwo One of two is matching (XOR) Validatable Control 2 CompareValue Is selected
All All are matching (AND) Validatable Control 2+ CompareValue Is selected
AtLeastNotOne At least one is not matching (NAND) Validatable Control 2+ CompareValue Is selected
Count A specific count is matching Validatable Control 2+ CompareValue and CompareCount Is selected and CompareCount
MinCount A minimum count is matching Validatable Control 2+ CompareValue and CompareCount Is selected and CompareCount
MaxCount A maximum count is matching Validatable Control 2+ CompareValue and CompareCount Is selected and CompareCount
NotCount A speficic count is not matching Validatable Control 2+ CompareValue and CompareCount Is selected and CompareCount
Equals A value is matching Validatable Control 1 CompareValue Is selected
NotEquals A value is not matching Validatable Control 1 CompareValue Is selected
Expression An expression is matching Validatable Control 1 RegEx of CompareValue Not supported
NotExpression An expression is not matching Validatable Control 1 RegEx of CompareValue Not supported
RequiredFieldValidator A RequiredFieldValidator is valid Validator Control 1 Validator result Not supported
NotRequiredFieldValidator A RequiredFieldValidator is invalid Validator Control 1 Validator result Not supported
CompareValidator A CompareValidator is valid Validator Control 1 Validator result Not supported
NotCompareValidator A CompareValidator is invalid Validator Control 1 Validator result Not supported
RangeValidator A RangeValidator is valid Validator Control 1 Validator result Not supported
NotRangeValidator A RangeValidator is invalid Validator Control 1 Validator result Not supported
RegularExpressionValidator A RegularExpressionValidator is valid Validator Control 1 Validator result Not supported
NotRegularExpressionValidator A RegularExpressionValidator is invalid Validator Control 1 Validator result Not supported
CustomValidator A CustomValidator is valid Validator Control 1 Validator result Not supported
NotCustomValidator A CustomValidator is invalid Validator Control 1 Validator result Not supported

Scope Count describes the number of allowed control references. An invalid number of scope references will lead to a runtime exception.

Validation Type

The validation type determines how the result of the rule validation should be interpreted:

  • Prescription: The rules describe a state which has to be adhered to
    In case the input matches to the rules, validation is valid (default)
  • Prohibition: The rules describe a state which is not allowed
    In case the input matches to the rules, validation is invalid

Which validation type makes sense depends on the scenario at hand. The following examples demonstrate the validation type with several concrete real world examples.

Validation Controls

The library attached to the article contains two validation controls:

  • RuleValidator: a validator with a single rule
  • MultiRuleValidator: a validator with an arbitrary number of rules

The RuleValidator is intended for simple scenarios where validation is achieved by a single rule. The following example enforces at least one text input:

<asp:TextBox runat="server" ID="Edit1" />
<asp:TextBox runat="server" ID="Edit2" />
<asp:TextBox runat="server" ID="Edit3" />

<val:RuleValidator runat="server" Display="None" ErrorMessage="Please enter at least one text"
  Operation="AtLeastOne" Scope="Edit1,Edit2,Edit3" />
<asp:ValidationSummary runat="server" />

<asp:Button runat="server" Text="Submit" OnClick="SubmitClick" />

Using the MultiRuleValidator it is possible to combine multiple rules in one validation. The validator is considered valid when all rules are fulfilled (logic AND). The following login example allows a user to either login with existing credentials or to register. In case of an existing user the presence of password input is checked:

<asp:Label runat="server" Text="E-Mail:" />
<asp:TextBox runat="server" ID="EmailEdit" />
<br />
<val:ValidatableRadioButton runat="server" ID="NewCustomerOption" Text="New Customer"
  GroupName="LoginGroup" Checked="True" />
<br />
<val:ValidatableRadioButton runat="server" ID="ExistingCustomerOption" Text="Password:"
  GroupName="LoginGroup" />
<asp:TextBox runat="server" ID="PasswordEdit" />

<val:RuleValidator runat="server" Display="None" ErrorMessage="Please enter a valid E-Mail address"
  Scope="EmailEdit" Operation="Expression" CompareValue="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
<val:MultiRuleValidator runat="server" Display="None" ErrorMessage="Please enter your password"
  ValidationType="Prohibition">
  <val:Rule Operation="Equals" Scope="ExistingCustomerOption" Source="Option" CompareValue="True" />
  <val:Rule Operation="Equals" Scope="PasswordEdit" CompareValue="" />
</val:MultiRuleValidator>
<asp:ValidationSummary runat="server" />

<asp:Button runat="server" Text="Login" OnClick="LoginClick" />

The next example demonstrates how to enforce a valid credit card number depending on the credit card type. For each credit card type, the input is validated according to a specific regular expression:

<asp:Label runat="server" Text="Credit Card:" />
<asp:ListBox runat="server" ID="CardList">
  <asp:ListItem Text="Visa" Value="Visa" />
  <asp:ListItem Text="Master Card" Value="MasterCard" />
  <asp:ListItem Text="American Express" Value="AmericanExpress" />
</asp:ListBox>
<asp:TextBox runat="server" ID="CardEdit" />

<asp:RequiredFieldValidator runat="server" ErrorMessage="Please select the Card" Display="None"
  ControlToValidate="CardList" />
<val:MultiRuleValidator runat="server" Display="None" ErrorMessage="Invalid Visa Number"
  ValidationType="Prohibition">
  <val:Rule Operation="Equals" Scope="CardList" CompareValue="Visa" />
  <val:Rule Operation="NotExpression" Scope="CardEdit" CompareValue="^4[0-9]{12}(?:[0-9]{3})?$" />
</val:MultiRuleValidator>
<val:MultiRuleValidator runat="server" Display="None" ErrorMessage="Invalid Master Card Number"
  ValidationType="Prohibition">
  <val:Rule Operation="Equals" Scope="CardList" CompareValue="MasterCard" />
  <val:Rule Operation="NotExpression" Scope="CardEdit" CompareValue="^5[1-5][0-9]{14}$" />
</val:MultiRuleValidator>
<val:MultiRuleValidator runat="server" Display="None" ErrorMessage="Invalid American Express Number"
  ValidationType="Prohibition">
  <val:Rule Operation="Equals" Scope="CardList" CompareValue="AmericanExpress" />
  <val:Rule Operation="NotExpression" Scope="CardEdit" CompareValue="^3[47][0-9]{13}$" />
</val:MultiRuleValidator>
<asp:ValidationSummary runat="server" />

<asp:Button runat="server" Text="Submit" OnClick="SubmitClick" />

Composite Validation

To cover scenarios with even more requirements it is possible to incorporate the standard ASP.NET validators into the rule framework. By assigning the corresponding Operation and referencing the validator via Scope, it is very easy to reuse the functionality of the standard ASP.NET validators:

<val:ValidatableCheckBox runat="server" ID="TimeRangeOption" Text="Restrict to time range" />
<br />
&nbsp;&nbsp;<asp:Label runat="server" Text="From: " />
&nbsp;<asp:TextBox runat="server" ID="StartEdit" />
&nbsp;&nbsp;<asp:Label runat="server" Text="Until: " />
&nbsp;<asp:TextBox runat="server" ID="EndEdit" />

<asp:CompareValidator runat="server" ID="TimeRangeValidator" Type="Date" Operator="LessThan"
  ControlToValidate="StartEdit" ControlToCompare="EndEdit" />
<val:MultiRuleValidator runat="server" Display="None" ErrorMessage="Invalid time range"
  ValidationGroup="SettingValidation" ValidationType="Prohibition">
  <val:Rule Operation="Equals" Scope="TimeRangeOption" Source="Option" CompareValue="True" />
  <val:Rule Operation="NotCompareValidator" Scope="TimeRangeValidator" />
</val:MultiRuleValidator>
<asp:ValidationSummary runat="server" ValidationGroup="SettingValidation" />

<asp:Button runat="server" Text="Save" ValidationGroup="SettingValidation" OnClick="SaveClick" />

When using composite validators it important to ensure that the referenced validators will not be run multiple times. This can be prevented by putting the rule validator into a separate ValidationGroup.

The rule validators can also be used in cases where multiple standard ASP.NET validators should be combined into an atomic rule according to variable criteria.

Points of Interest and Delimitations

  • The required JavaScript code on client side is an embedded resource of the library and is being loaded into the web browser as a WebResource
  • Within the page validation, the rule validators can be combined as desired with the standard ASP.NET validators
  • Validation of the control CheckBoxList is currently not supported
  • Further information in regard to ASP.NET validation can be found under MSDN, MSDN and MSDN

History

  • 18th April, 2012: Initial release - v1.1.0.0
    • new rule operations MinCount and MaxCount
    • new example: product selection
  • 17th April, 2012: Initial release - v1.0.0.0