Click here to Skip to main content
15,884,099 members
Articles / Web Development / ASP.NET

Rule Based Validation for ASP.NET

Rate me:
Please Sign up or sign in to vote.
4.98/5 (26 votes)
18 Apr 2012CPOL7 min read 51.4K   1.3K   56   13
Enhanced web page validation based on multiple rules at client and server side.

Image 1

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:

C#
// ------------------------------------------------------------------------
[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

Image 2

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 TargetScope CountValue Condition Option Condition
AtLeastOne At least one is matching (OR)Validatable Control2+CompareValueIs selected
None None is matching (NOR)Validatable Control2+CompareValueIs selected
OneOfTwo One of two is matching (XOR)Validatable Control2CompareValueIs selected
All All are matching (AND)Validatable Control2+CompareValueIs selected
AtLeastNotOne At least one is not matching (NAND)Validatable Control2+CompareValueIs selected
Count A specific count is matchingValidatable Control2+CompareValue and CompareCountIs selected and CompareCount
MinCount A minimum count is matchingValidatable Control2+CompareValue and CompareCountIs selected and CompareCount
MaxCount A maximum count is matchingValidatable Control2+CompareValue and CompareCountIs selected and CompareCount
NotCount A speficic count is not matchingValidatable Control2+CompareValue and CompareCountIs selected and CompareCount
Equals A value is matchingValidatable Control1CompareValueIs selected
NotEquals A value is not matchingValidatable Control1CompareValueIs selected
Expression An expression is matchingValidatable Control1RegEx of CompareValueNot supported
NotExpression An expression is not matchingValidatable Control1RegEx of CompareValueNot supported
RequiredFieldValidator A RequiredFieldValidator is validValidator Control1Validator resultNot supported
NotRequiredFieldValidator A RequiredFieldValidator is invalidValidator Control1Validator resultNot supported
CompareValidator A CompareValidator is validValidator Control1Validator resultNot supported
NotCompareValidator A CompareValidator is invalidValidator Control1Validator resultNot supported
RangeValidator A RangeValidator is validValidator Control1Validator resultNot supported
NotRangeValidator A RangeValidator is invalidValidator Control1Validator resultNot supported
RegularExpressionValidator A RegularExpressionValidator is validValidator Control1Validator resultNot supported
NotRegularExpressionValidator A RegularExpressionValidator is invalidValidator Control1Validator resultNot supported
CustomValidator A CustomValidator is validValidator Control1Validator resultNot supported
NotCustomValidator A CustomValidator is invalidValidator Control1Validator resultNot 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.NET
<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.NET
<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.NET
<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:

ASP.NET
<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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
👨 Senior .NET Software Engineer

🚀 My Open Source Projects
- Time Period Library 👉 GitHub
- Payroll Engine 👉 GitHub

Feedback and contributions are welcome.



Comments and Discussions

 
Question5 Pin
EmanuelPirovano7-Mar-17 22:31
EmanuelPirovano7-Mar-17 22:31 
GeneralMy vote of 5 Pin
KRadolov29-Aug-13 21:22
KRadolov29-Aug-13 21:22 
Excellent code
AnswerRe: My vote of 5 Pin
Jani Giannoudis4-Sep-13 4:00
Jani Giannoudis4-Sep-13 4:00 
GeneralThank you for the credit, Jani Pin
Adam Tibi7-Mar-13 1:39
professionalAdam Tibi7-Mar-13 1:39 
AnswerRe: Thank you for the credit, Jani Pin
Jani Giannoudis26-May-13 11:25
Jani Giannoudis26-May-13 11:25 
GeneralMy vote of 5 Pin
zhaojicheng7-May-12 6:31
zhaojicheng7-May-12 6:31 
AnswerRe: My vote of 5 Pin
Jani Giannoudis7-May-12 19:53
Jani Giannoudis7-May-12 19:53 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey19-Apr-12 23:31
professionalManoj Kumar Choubey19-Apr-12 23:31 
AnswerRe: My vote of 5 Pin
Jani Giannoudis20-Apr-12 10:10
Jani Giannoudis20-Apr-12 10:10 
GeneralMy vote of 5 Pin
Othello7417-Apr-12 9:25
Othello7417-Apr-12 9:25 
AnswerRe: My vote of 5 Pin
Jani Giannoudis17-Apr-12 22:02
Jani Giannoudis17-Apr-12 22:02 
GeneralMy vote of 5 Pin
Anurag Gandhi17-Apr-12 3:39
professionalAnurag Gandhi17-Apr-12 3:39 
AnswerRe: My vote of 5 Pin
Jani Giannoudis17-Apr-12 4:11
Jani Giannoudis17-Apr-12 4:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.