Self Validating Text Box - 2






4.50/5 (15 votes)
Feb 10, 2004
4 min read

134341

1140
This article extends self validating Text Box control to other data types and Min and Max value checking.
Introduction
The motivation for this article lies at Self Validating ASP.NET Text Box by Patrick Meyer of NASA in Mission Planning Systems. Please read this excellent article for the self-validating control first. Like many other .NET developers, I like self-validating controls due to their simplicity. Microsoft provides CompareValidator
and it serves the same purpose in general. Through self-validating control, I have to do less typing and there are less controls on the web form. This article validates the richness of .NET framework.
Pat showed us how to implement IValidator
interface with a TextBox
and I struggled to implement data type checking for various data types so that we do not need to implement different controls for various data types.
An excellent tool by Jay Freeman shortened my struggle to implement the same functionality as provided by CompareValidator
. You can download this free tool from here. This tool goes through all Microsoft assemblies and somehow it converts IL code into C#. I looked how Microsoft implemented CompareValidator
control and I used the same API for range and data type checking. It took me a little time to implement this. Through Jay's tool, you can peep through how great minds at Microsoft do the development.
I desire to have a self-validating TextBox
control that can check if the field is a required field or not. This should also perform a min or max value validation by using MinValue
and MaxValue
properties of the TextBox
. I should be able to specify the data type of the input in the text box. Since CompareValidator
does this already, Anakrino tool helped me figure out how it was done internally. The data types implemented are String
, Currency
, Double
, Date
and Integer
.
Implementing the Compare of BaseCompareValidator
After going through the source of various methods in BaseValidator
, BaseCompareValidator
and CompareValidator
, I noticed that I could use BaseCompareValidator.CanConvert
method to check the data type validity of the input data. I also need to check for the range or compare the input value for different data types against a given MinValue
or MaxValue
property of the control. If I define TextBox
control to be a Date
then my date should be within MinValue
or MaxValue
. If data type is Currency
then my value cannot be greater than say 10,000.
A simple rule that I follow for MinValue
or MaxValue
is that if these values are blank then I do not need to perform a validation. In real life situation, we would like to bind MinValue
and MaxValue
to the database. I would recommend using two-way data binding approach for a web form in general. There is an excellent article on this topic here. If you use two-way data binding with self-validating TextBox
in your real life projects, you do not have to type much code to unbind data.
We hope that ASP.NET "Whidbey" will implement two way data binding and that will reduce coding for generic type of web forms implementing typed DataSet
s.
To implement range checking, there is a protected method Compare
in BaseCompareValidator
class. Since I am already inheriting my TextBox
class from System.Web.UI.WebControls.TextBox
, C# will not allow multiple inheritance. I had to create another class to get the advantage of this protected
method.
public class EADCompare : BaseCompareValidator
{
public static bool DoCompare(string from, string to,
ValidationCompareOperator cmp, ValidationDataType objType)
{
if (to == null || to.Length == 0) return true;
return BaseCompareValidator.Compare(from, to, cmp, objType);
}
protected override bool EvaluateIsValid()
{
return true;
}
}
The compiler forces you to implement EvaluateIsValid
method. I just return true
from this. We are not implementing this class in a true sense to implement a separate validator. We just want to access the Compare
method to do the work instead of writing custom code.
To show a little graphic image along side with your text box when your validation fails is a neat idea. I borrowed this implementation by overriding Render
method of TextBox
as follows:
protected override void Render(HtmlTextWriter writer)
{
base.Render (writer);
if (this.ErrorMessage != null && this.ErrorMessage != "" )
writer.Write(" <img src=\"images/stop.gif\" alt=\"" +
this.ErrorMessage + "\")\">");
}
The error message shows up when you hover your mouse on this image. All other validation messages show up in the validation summary control as if you have used Microsoft provided validator controls. Please read Patrick’s article for details.
The validate method of the TextBox
provides Required
, MinValue
and MaxValue
validation against data types String
, Currency
, Double
, Date
and Integer
.
public void Validate()
{
this.IsValid = true;
bool isBlank = (this.Text.Trim() == "");
if (Required)
{
if (isBlank)
{
this.ErrorMessage =
String.Format("'{0}' is a required field.",
this.UserFieldName);
this.IsValid = false;
}
}
if (!isBlank)
{
// if not blank then check the datatype of the control.
bool isOk =
BaseCompareValidator.CanConvert(this.Text,GetDataType());
if (!isOk)
{
this.ErrorMessage =
String.Format("'{0}' is not a valid data type.",
this.UserFieldName);
this.IsValid = false;
return;
}
// If MinValue is not empty then check if Text is less
// than MinValue. If yes, validate false.
isOk = EADCompare.DoCompare(this.Text, MinValue,
ValidationCompareOperator.GreaterThanEqual,GetDataType());
if (!isOk)
{
this.ErrorMessage = String.Format("'{0}' " +
"can not have value less than {1}",
this.UserFieldName, this.MinValue);
this.IsValid = false;
return;
}
// If MaxValue is not empty then check if Text
// is more than MinValue. If yes, validate false.
isOk = EADCompare.DoCompare(this.Text, MaxValue,
ValidationCompareOperator.LessThanEqual,
GetDataType());
if (!isOk)
{
this.ErrorMessage = String.Format("'{0}' " +
"can not have value more than {1}",
this.UserFieldName, this.MaxValue);
this.IsValid = false;
return;
}
}
}
< %@Register TagPrefix="EAD" Namespace="EAD.WebControls" Assembly="General" % >
To use this TextBox
control in your web form, you need to first register the control in your ASPX page. Replace the name of the namespace and assembly, if you put this TextBox
class in your favorite namespace and assembly.
A typical syntax of the TextBox
in your page will look like this:
<asp:label id="txtErrorMessage" runat="server"
EnableViewState="False"></asp:label>
<EAD:TextBox id="TextBox1" runat="server" UserFieldName="Double Test"
Required="False" MinValue="123.456" MaxValue="789023.345"
TextType="Double"></EAD:TextBox>
<EAD:TextBox id="Textbox2" runat="server" Width="64px"
UserFieldName="Date Test" Required="True" MaxValue="12/12/2000"
MinValue="1/1/2000" TextType="Date"></EAD:TextBox>
<EAD:TextBox id="Textbox3" runat="server" Width="64px"
UserFieldName="Integer Test" Required="True" MaxValue="100"
MinValue="10" TextType="Integer"></EAD:TextBox>
<EAD:TextBox id="Textbox4" runat="server" Width="64px"
UserFieldName="Currency Test" Required="True" MaxValue="12,000"
MinValue="10,000" TextType="Currency"></EAD:TextBox>
<EAD:TextBox id="Textbox5" runat="server" Width="64px"
UserFieldName="String Test" Required="False" MaxValue="P"
MinValue="B" TextType="String"></EAD:TextBox>
The attached ZIP file has three files. They are a sample ASPX page, TextBox
class and Stop.gif image. The sample page has five different types of validations using different data types.
The screen capture is below:
Summary
Self validating controls give you flexibility to attach simple validation at the control itself. The same approach can be extended to other types of web controls. It should be fairly simple and straight forward.