Blue Theme Orange Theme Green Theme Red Theme
 
HeaderAd
Home | Forums | Videos | Photos | Blogs | E-Books | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article 
 Login Close
User Id:
Password:
 
Forgot Password
Forgot Username
Why Register
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
 Resources  
Close
 Our Network  
Close
Search :       Advanced Search »
Home » XML .NET » XML Driven Validation

XML Driven Validation

This article/tutorial tells us to develop a generic XML based Validation engine to be used in any Web application.

Technologies: .NET 1.0/1.1, ASP.NET 1.0, Common Controls, XML,Visual C# .NET
Total downloads :
Total page views :  10802
Rating :
 4/5
This article has been rated :  3 times
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
 
ArticleAd
Become a Sponsor



Importance of Validation

Input validation ensures a user not only enters or selects values when required but also enters appropriate and correctly formatted values. Any user input form/window that support insert, update, delete or any calculated functions are all common scenarios where input validation should be implemented.

It's important to ensure that data you store in a database is standardized, comprehensive and complete. Invalid phone numbers, incorrectly formatted email addresses or empty addresses amongst other things will undermine the effectiveness and quality of the data in your web application.

One should also be aware of script errors that might be caused by an application user entering incorrect variable types e.g. a user entering a alphanumeric value in an amount calculation box when an integer is required. Input validation also protects against a malicious user attempting to directly enter HTML, Javascript, SQL or other inappropriate scripts.

The Validation Controls

The ASP.Net provides 6 validation controls including the ValidationSummary control. These are :

  • RequiredFieldValidator 
  • RegularExpressionValidator 
  • RangeValidator
  • CompareValidator
  • CustomValidator
  • ValidationSummary

The ASP.NET validation controls make form validation a lot faster and easier. Because we all know what the properties of these controls and how to use them, I am not going to explain the same.

The Problem Identified

With ASP.Net validation can now be accomplished in a matter of minutes and have the flexibility both in the types of validation and the error message that is displayed to the end user. Where in a small 5-10 page of data entry application, hard coding error messages and regular expression into the validation controls is the easiest and fastest way to develop. 

One will likely wind up with 2 or 3 "Phone Number" textboxes, each having a "Phone" required field validator and regular expression validator, each with their own hard-coded error message. Though not an ideal situation, it is certainly manageable.

But, as the page count increases, however, maintaining these strings becomes a headache, especially when the changes are more frequent in showing error message syntax. When you ask to change "Phone is a required field" to "Please enters Phone number" how many lines of code are touched?

The Solution Identified - An XML Based Validation Approach 

Below are the requirements for the solution of the above mentioned problem:

  1. Developers should be able to view and edit any validation with minimal effort.
  2. To provide a common way to validate the same kind of input field in different pages in an application. 
  3. The performance must be fast. These values could be accessed from every page in the application.

To implement the above I have used the following:

  1. An XML file to store the input field key, max length, min length, error messages and regular expression.
  2. A C# class in a singleton approach that stores the XML data in cached manner and certain methods to make use of this XML based validation engine in ASP.NET pages/forms. 

The XML File (ScreenValidations.xml) 

<?xml version="1.0" encoding="utf-8" ?>

<!-- This XML provides the elements to define the input data validations for various screens of this web application. -->

<Validations>

  <Field>

    <Name>PolicyNumber</Name>

    <MaxLength>7</MaxLength>

    <MinValue>0</MinValue>

    <MaxValue>0</MaxValue>

    <RegEx>^[a-zA-Z]{0,50}$</RegEx>

    <RegExErrorMessage>Invalid Policy Number</RegExErrorMessage>

    <RequiredErrorMessage>Please enter the Policy Number </RequiredErrorMessage>

    <RangeErrorMessage>Invalid PolicyNumber</RangeErrorMessage>

  </Field>

  <Field>

    <Name>Date</Name>

    <MaxLength>10</MaxLength>

    <MinValue>0</MinValue>

    <MaxValue>0</MaxValue>

    <RegEx>^\d{1,2}\/\d{1,2}\/\d{4}$</RegEx>

    <RegExErrorMessage>Invalid Date. Date must be in MMDDYYYY format</RegExErrorMessage>

    <RequiredErrorMessage>Date must be in MMDDYYYY format</RequiredErrorMessage>

    <RangeErrorMessage></RangeErrorMessage>

  </Field>

  <Field>

    <Name>Price</Name>

    <MaxLength>13</MaxLength>

    <MinValue>0</MinValue>

    <MaxValue>0</MaxValue>

    <RegEx>(?n:(^\$?(?!0,?\d)\d{1,3}(?=(?&lt;1&gt;,)|(?&lt;1&gt;))(\k&lt;1&gt;\d{3})*(\.\d\d)?)$)</RegEx>

    <RegExErrorMessage>Invalid Premium amount. Digits to the left of the decimal point can optionally be formatted with
      commas, 
in standard US currency format. If the decimal point is present, it must be followed by exactly two digits
      to the right.
Matches an optional preceding dollar sign. </RegExErrorMessage>

    <RequiredErrorMessage>Please enter the Premium Amount</RequiredErrorMessage>

    <RangeErrorMessage>Invalid Premium </RangeErrorMessage>

  </Field>

</Validations> 

The Elements of the above XML File 

  • <Field> defines a field and its child elements that would be used in the calling code for validation.
  • <Name> is the unique key used in the calling code to access the validation expression and other values.
  • <MaxLength> is the maxlength property of the control.
  • <MinValue> & <MaxValue> are used for range validations if any.
  • <RegEx> is the regular expression that would be assigned  to the validation expression property of a control in your application at runtime.
  • <RegExErrorMessage> is the message to display to the user when the regular expression validation fails.         
  • <RequiredErrorMessage> is the message to display to the user when the required control left empty or unselected.         
  • <RangeErrorMessage> is the message to display to the user when the input value entered is not in the range defined. 

The above XML file can be modified throughout the development process as and when the new fields are being added / removed and/or whenever any changes are requested. 

The Field Validation Class that loads the XML File into memory (Validation.cs)

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Collections.Specialized;

using System.Web.Configuration;

 

namespace Components

{

    /// <summary>

    ///This class provides common storage for multiple values based on a key.

    ///Screen input field controls would be the key and the values stored

    ///would be RequiredErrorMessage, RegularExpressionErrorMessage, and RegularExpression.

    ///These values will be accessed on the first page load of nearly every page in the web application.

    ///This Validation process consists of the following:

    ///An XML file used to store the keys and values (ScreenValidations.xml).

    ///A singleton class (Validation) that stores the XML data in memory.

    ///A method named BindValidation() that appears on every page containing a validator or textbox.

    ///The first time a page loads a call is made to BindValidation(),

    ///which retrieves the values from the singleton and assigns them to the

    ///appropriate validator or textbox.

    ///The Validation class is NotInheritable, meaning it cannot be extended through inheritance.

    ///This class is not designed to be a base class and inheriting from it would not

    ///make much sense from an object oriented perspective

    /// </summary>

 

    public sealed class Validation

    {

        private static Validation validationInstance = new Validation();

 

        /// <summary>

        /// HybridDictionary cachedValidationFields, populated in Validation's constructor,

        /// is the core of this class, as it holds the collection of ValidationField objects.

        /// cachedValidationFields can only be accessed through the Field property,

        /// which retrieves a particular ValidationField object from the collection

        /// based on a string key.

        /// </summary>

 

        private HybridDictionary cachedValidationFields = new HybridDictionary();

 

        public static Validation Instance

        {

            get { return validationInstance; }

        }

 

        public static ValidationField Field(string fieldName)

        {

            return ((ValidationField)(validationInstance.cachedValidationFields[fieldName]));

        }

 

        /// <summary>

        /// Contains the structure for the ValidationField

        /// </summary>

 

        public class ValidationField

        {

            /// <summary>

            /// Name is the key used in the calling code to retrieve the appropriate values.

            /// </summary>

 

            public String Name = String.Empty;

 

            /// <summary>

            /// MaxLength is another property that is typically hard-coded

            /// and duplicated throughout code.

            /// It corresponds to the MaxLength property of a textbox.

            /// </summary>

 

            public int MaxLength = 0;

 

            /// <summary>

            /// Min Value is another property that is typically hard-coded and

            /// duplicated throughout code. It corresponds to the min value for a range validator.

            /// </summary>

 

            public int MinValue = 0;

 

            /// <summary>

            /// Max Value is another property that is typically hard-coded and

            /// duplicated throughout code. It corresponds to the max value for a range validator.

            /// </summary>

 

            public int MaxValue = 0;

 

            /// <summary>

            /// RegEx is the regular expression that would be assigned to the

            /// ValidationExpression property of a RegularExpressionValidator.

            /// </summary>

 

            public String RegEx = String.Empty;

 

            /// <summary>

            /// RegExErrorMessage is the error message to display if the regular expression validation fails.

            /// </summary>

 

            public String RegExErrorMessage = String.Empty;

 

            /// <summary>

            /// RequiredErrorMessage is the error message to display

            /// if the required field validation fails.

            /// </summary>

 

            public String RequiredErrorMessage = String.Empty;

 

            /// <summary>

            /// RangeErrorMessage is the error message to display

            /// if the range field validation fails.

            /// </summary>

 

            public String RangeErrorMessage = String.Empty;

        }

 

        /// <summary>

        ///The constructor is only called once, the first time this class is instantiated.

        ///Every time an instance of this object is called after the first time,

        ///the "in memory" copy contained in validationInstance is used.

        ///The constructor performs the basics.

        ///It reads ScreenValidations.xml into memory, in a DataSet.

        ///It reads through each row of the DataSet and populates a new ValidationField object.

        ///Finally, it adds the ValidationField object to the cachedValidationFields collection.

        ///Once the DataSet is populated it is not changed until it is reloaded from the

        ///XML when the application is restarted.

        /// </summary>

 

        private Validation()

        {

            try

            {

                #region Reads ScreenValidations.xml into memory

 

                DataSet ds = new DataSet();

                //DataRow dr;

                string ValidationFilePath = WebConfigurationManager.AppSettings["ScreenValidation"].ToString();

                ds.ReadXml(System.Web.HttpContext.Current.Server.MapPath(ValidationFilePath));

 

                #endregion

 

                foreach (DataRow dr in ds.Tables[0].Rows)

                {

                    #region Reads through each row of the DataSet and populates a new Field object

 

                    ValidationField Field = new ValidationField();

                    Field.Name = dr["Name"].ToString();

                    Field.MaxLength = Utilities.Util.ConvertInt(dr["MaxLength"], System.Globalization.NumberStyles.Integer);

                    Field.MinValue = Utilities.Util.ConvertInt(dr["MinValue"], System.Globalization.NumberStyles.Integer);

                    Field.MaxValue = Utilities.Util.ConvertInt(dr["MaxValue"], System.Globalization.NumberStyles.Integer);

                    Field.RegEx = dr["RegEx"].ToString();

                    Field.RegExErrorMessage = dr["RegExErrorMessage"].ToString();

                    Field.RequiredErrorMessage = dr["RequiredErrorMessage"].ToString();

                    Field.RangeErrorMessage = dr["RangeErrorMessage"].ToString();

 

                    #endregion

 

                    #region Adds the Field object to the cachedValidationFields collection.

 

                    cachedValidationFields.Add(Field.Name, Field);

 

                    #endregion

                }

            }

            catch (Exception ex)

            {

                throw ex;

            }

        }

 

        /// <summary>

        /// The Reset method allows for dynamic reloading of ScreenValidations.xml during runtime.

        /// Any screen/page/class could very easily call this method in a event handler to

        /// allow administrators to reload ScreenValidations.xml on the fly without restarting

        /// the application.

        /// </summary>

 

        public static void Reset()

        {

            validationInstance = new Validation();

        }

    }

} 

How to access/implement the Validation in web page 

Suppose you have already designed your web page and placed the appropriate validation controls.  A method named BindValidation() that appears on every page containing a validator or textbox. The first time a page loads a call is made to BindValidation(),which retrieves the values from the singleton and assigns them to the appropriate validator or textbox.

protected void Page_Load(object sender, System.EventArgs e)

{

    if (!IsPostBack)

    {

        BindValidation();

    }

} 

 

protected void BindValidation()

{

    try

    {

        txtDate.Validate = true;

        txtDate.ErrorMessage = Validation.Field("Date").RequiredErrorMessage;

        txtDate.RegularExpression = Validation.Field("Date").RegEx;

        txtDate.RegularExpErrorMessage = Validation.Field("Date").RegExErrorMessage;

 

        txtPrice.Validate = true;

        txtPrice.ErrorMessage = Validation.Field("Price").RequiredErrorMessage;

        txtPrice.RegularExpression = Validation.Field("Price").RegEx;

        txtPrice.RegularExpErrorMessage = Validation.Field("Price").RegExErrorMessage;

    }

    catch (Exception ex)

    {

        //throw;

    }

} 

Advantage and Disadvantage of this approach

The main advantage of this approach is the maintainability provided by storing the myriad of string values in a single repository. In addition, using XML means only a text editor is required to modify these values, eliminating the need for recompilation. Finally, this approach allows the web and business tier to easily share the same regular expressions and error messages.  

One disadvantage of this approach is that the ViewState is slightly larger than when hard-coding the values into the validators. When the values are hard-coded they are compiled into the dll, but when they are set dynamically at runtime they must be passed in the ViewState. This should be ok in the applications where performance is not a bigger issue. 

Conclusion

Maintenance is a nightmare for large applications that comes with many challenges. As the applications grow they tend to contain large quantities of repetitive information. The Validation class offers an easy to maintain, XML-based solution to an otherwise difficult problem.  


Login to add your contents and source code to this article
 [Top] Rate this article
 About the author
 
Subal Mishra
He has Masters degree in the field of Information Technology and Microsoft Certified Professional  with over ten years of experience in Project Management, System Design, Implementation and strategic consulting of web based and intranet based systems using Microsoft Technologies. He has a strong foundation in OOAD methodologies, system analysis and design.
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Boost the performance of your .NET applications
“ANTS Profiler took us straight to the specific areas of our code which were the cause of our performance issues." Terry Phillips, Sr. Developer, Harley-Davidson Dealer Systems. Download your free trial of ANTS Profiler.
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today.  With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications.  Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
 
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
 
 Post a Feedback, Comment, or Question about this article
Subject:  
Comment:  
ArticleAd
Become a Sponsor
Latest Comments:
Subject Posted By Posted On
Great ArticleTintin3/21/2007
Very simply written. Though it would be nice to include a little heads up on Regular Expressions or a link to a resource to learn more about how they work. They are a beast unto themselves.
Reply | Email | Delete | Modify | 
Some improvements...eran4/16/2007
Hi, Furstable, nice article and good approach to the problem. Secondly, the usage with DataSet regarding of storing the data in the memory is to be lacking... It is hard and not right to access this way to the data stored there, and don't talk about that there is a chance of an error in run time... I suggest you to create a custom data object that will be serializable and will map the data from the XML file directly to the data object. This is much more right and fast doing, and the best feature here is the accessibility to the object properties. With regards, Eran Nachum, visit my blog at: http://www.eranachum.com
Reply | Email | Delete | Modify | 
code errorisunshine2/14/2008
Changing values in the xml file won't take effect until you resave and compile the cs file...
Reply | Email | Delete | Modify | 

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2009.6.2
 © 1999 - 2009  Mindcracker LLC. All Rights Reserved