Archive for January, 2012

Validation in ASp.net

Introduction

It makes no difference what kind of development you are working on, user input validation is always an important and often troublesome issue.

What data needs to be validated? What are the valid conditions? Do we need to report every error in one pass or allow the user to correct one error at a time? Do we validate on the client or on the server? The questions go on.

Worse than that, the code can quickly get unmanageable, especially where we try to validate everything in one pass. Nested ifs, deconstructing strings, building up lists of error messages, endless comments trying to make some sense of it.

It is my personal opinion that everything that can be updated by anyone else but me should be validated at every opportunity and that we should always validate everything in one pass. But that does not mean that I have never tried to dodge the bullet on a tight deadline.

In some respects, it can be worse for the web page developer. It is important to validate as much as possible at the client to save on bandwidth, but HTTP requests are so easy to fake; the same data

needs

to be validated again on the server, if you want any kind of security.

Another problem can arise if the customer wants you to mark the invalid fields and then list the errors in one place (a common user-friendly convention in web-page design).

It is hard to imagine someone who enjoys writing validation code, and that goes double for classic ASP developers. Thankfully, the .NET framework has gone a long way to alleviate the problem for the ASP.NET developer with the introduction of six all-encompassing and developer-friendly validation controls:


RequiredFieldValidator
Ensure that a mandatory field is populated.

CompareValidator
Compare one control with another or with a literal.

RangeValidator
Check that data is within a given range.

RegularExpressionValidator
Use where data must match a given Regex format.

CustomValidator
Use a custom validation function to validate a control.

ValidationSummary
Collate the results of an entire form’s validation.

This article assumes a basic knowledge of adding controls to a web form and setting the properties and event handlers. It attempts to give a general overview of these controls and how to use them to perform simple practical tasks.

All examples use C# with

GridLayout

pages. But anything in this article should easily translate to VB.NET and / or

FlowLayout

pages.

(continue reading…)

BaseValidator controls

All of the above, with the single exception of

ValidationSummary

, are derived from the

BaseValidator

class and share some functionality.

The first four validation controls are tailored for specific purposes and designed to validate an identical condition on both the client and the server. Each generates some purpose-specific JavaScript (using

WebUIValidation.js

, in the

aspnet_client

web) to validate the input control that you point to against the condition that the given validation control is designed to handle.

The

CustomValidator

allows you to define your own validation routines, using an event handler on the client, server or both.

The actual client-side validation takes place in events triggered by a change of value in the control you are validating and when you try to submit the form. The server-side validation takes place when you post back the form and the validation results can be accessed using the

Form

class’s

.IsValid

property.

Each control’s properties look reasonably similar. Apart from the standard font and formatting properties, each of the standard controls has the following common properties, derived from

BaseValidator

:


.ControlToValidate
Name of the control we are validating.

.ErrorMessage
The error message related to an invalid condition.

.Text
Text to display in this control if invalid.

.EnableClientScript
Validate client-side and server-side.

.IsValid
The validation result of this control

ControlToValidate

A

string

containing the name of the

Control

object that the validation control will examine. This control must be developed using the

ValidationPropertyAttribute

.

Of the standard controls, the only ones marked with a

ValidationProperty

are:


  • TextBox

  • ListBox

  • DropDownList

  • RadioButtonList

  • HtmlInputText

  • HtmlInputFile

  • HtmlSelect

  • HtmlTextArea

It is worth bearing this in mind if you are ever developing a control that may require validation. You should always prefix the class definition with

[ValidationProperty("MyProperty")]

(where

MyProperty

is the name of the property that can be changed by the user input, usually text).

ErrorMessage

This defines the message related to the invalid condition. This can be displayed in the control itself or passed to a

ValidationSummary

control.

Text

The text to be displayed in the control when the condition is not valid. If left blank, the control will display the

ErrorMessage

text.

If the difference between

.ErrorMessage

and

.Text

is confusing, read on. It should make sense by the time we examine the

ValidationSummary

control. Until then, we will only use the

.ErrorMessage

property (

.Text

should be left blank)

EnableClientScript

By default this is set to

true

and the

.ControlToValidate

will be validated twice, at the client and at the server.

If the

.EnableClientScript

property is set to

false

, then validation will be limited to the server.

IsValid

The only property not available to the WebForm designer,

.IsValid

contains the validation result for this control after the form’s validation has taken place.

This can be useful if you want to react differently when only part of the page is invalid.

Examples

 

The following sections will refer to a very simple example. As shown in the screenshot, this example will consist of a single

TextBox

being validated. You know the kind of thing: Leave your E-mail address here and we’ll send you something really nice for free.

(and then sell your email address to five hundred Email spammers)

Create a web form, containing only a

Label

(“Email Address:”), an empty

TextBox

, a submit

Button

and whichever

-Validator

control we are looking at. (see sample image)

The

ControlToValidate

property should always point to the

TextBox

and the

ErrorMessage

should contain something relevant to the validation we are working with.

Include some code in a

Button_Click

handler to redirect to another page when the button is clicked, but only if the page is valid.

private void myButton_Click(object sender, System.EventArgs e){ if (this.IsValid) Response.Redirect("anvokay.aspx", true);}

Or… if you are feeling lazy, you can download the sample code at the top of the page and unzip it into a new or existing web.


NOTE:

There is a strange behavior quirk in the interaction between web browsers and the .NET framework which means that if you hit

Enter

in a Single-

TextBox

form it will post back to the server but the

Button_Click

handler is not executed.

This is apparently a legacy browser issue where, for a single textbox form, the button name is not sent as part of the response, leaving .NET with no idea what triggered the postback.

Possible workarounds are:

  • Always physically click the Submit button rather than pressing Enter.
  • Include a second

    TextBox

    that does nothing, just to avoid this “feature”.

The RequiredFieldValidator

As the name suggests, the

RequiredFieldValidator

is normally used to validate that a mandatory field is populated. It can also be customized so that blank is a valid response and some other text means that nothing has been entered.

There is only one property unique to the

RequiredFieldValidator


.InitialValue
Consider this text to be “no change” and blank to be “updated”.

Example

Validate our simple form, using a

RequiredFieldValidator

, as seen in the example diagram above. If you hit the Submit button without entering any text, you can see that the form does not post back to the server, the JavaScript on the client-side catches the error and displays the error message that you gave it.

If you set

.EnableClientScript
to false

and run the application again, then you will see that the submit button now forces a postback but the field is still validated, so if a malicious user attempts to forge the HTTP request to bypass your validation, it will not be successful.

And there you have it. You have now successfully implemented ASP.NET validation with one control and one line of code (

if (this.IsValid)

). How easy can it be?

InitialValue

The

.InitialValue

property gives you an opportunity to enter some text into the

TextBox

and still ensure that it is edited before submission.

Try changing both the

RequiredFieldValidator.InitialValue

and

TextBox.Text

to “EMAIL ADDRESS” and running the application again.

You should find that if you do not change this text and simply hit “Submit”, you will get the error message as specified, but now if you blank the field then it is considered valid.

In many ways, this is a functionality overlap with the

CompareValidator

, as will become clear later on. But in some cases it is more sensible (i.e.. more readable) to use the

RequiredFieldValidator

- for example, validating that a

DropDownList

has changed from the “Please Select One…” default.

BaseCompareValidator controls

The

CompareValidator

and

RangeValidator

both compare values to literals or other user-entered data. The two controls inevitably contain some common functionality and thus are derived from the

BaseCompareValidator

class.

The

BaseCompareValidator

only offers us one property in addition to those offered by the

BaseValidator

class:


.Type
Allows strings of specific formats to be compared accurately.

This one property, however, is very important and includes several “gotchas” that you might need to be aware of.

Type

The

.Type

property can be used to define how a string is treated. If a textbox is used for numeric, date or currency values, you can use one of the

BaseCompareValidator

controls to validate the type of data entered or compare it to a value of the same type more accurately.

e.g.. If compared directly as strings, “90″ is greater than “100″; but if compared as numbers, “90″ is clearly less than “100″.

But be aware that both the Client and the Server validation will deal with the input data using the locale of the

Server

machine, unless you set the page or application

Culture
/ UICulture

properties (see globalization in MSDN).

If you do not set the

Culture

and, like me, you develop primarily on an English locale machine (date format: DD/MM/YYYY) and then run your sites live on a US locale server (date format: MM/DD/YYYY) then, as you can see from the screenshot above, the data will be validated differently in development from live.

The 10th of January

is

before the 1st of October, after all, whichever country you come from.

It is always worth noting on your page which format the user is expected to use (remembering that YYYY/MM/DD is considered culture-independent), but the more idiot-proof you make things, the bigger idiot the internet produces. You cannot guarantee that the user will pay attention to instructions and even if you ask for YYYY/MM/DD, you will still get someone trying to use MM/DD/YYYY without even suspecting that your machine has an English Locale.

It is strongly recommended that you always (even if you develop on the live machine, or one very similar) specify a

Culture

in the

Web.Config file

Once you have done this,

you

know exactly where you stand. You can request the date in format MM/DD/YYYY format and if the user chooses to ignore that and use a culture-independent style then there is no harm done.

If you do not specify a culture, even in the

@Page

clause, then you need to be especially careful when comparing to a literal, which may be treated differently in development from production (in fact may cause an exception, if the locale is different and the value becomes invalid). You

must

then use a culture-independent style for literal dates.

All of this applies equally to numerics in countries which take a comma (,) as a decimal point and to systems using different currency symbols.

Another thing to watch out for is that if any of the values being compared are not of the type the validation is expecting (and in the case of dates, this includes DD-MMM-YYYY, eg. 10-Jan-2003), the form data will be considered

valid

. The reason for this is that an extra

CompareValidator

(using the

DataTypeCheck

operator described below) gives you a way out of this and you would generally expect the error message to be different.

The CompareValidator

The

CompareValidator

is, at first glance, the least useful of the standard validation controls. However it does have its place and has plenty of designer properties (including the

BaseCompareValidator.Type

property, see above) to tweak its functionality in interesting ways.


.ControlToCompare
Compare the value in this control to the value of another control.

.Operator
In what way should we compare the values?

.ValueToCompare
Compare the value with a literal value.

Example

In the simple example, we can use this control to ensure that no one uses a specific E-mail address in the form (I mean, we don’t want someone registering us for our own spam E-mail scam, do we?).

Drop a

CompareValidator

in place of the

RequiredFieldValidator

; set the

.Operator

to

NotEqual

(why

Equal

would ever be the default is beyond me!) and the

.ValueToCompare

to your own E-mail address. Do not forget, of course, to set the

.ControlToValidate

and

.ErrorMessage

properties, as before.

When you run the application and try to enter your own email address into the form, the validator should give you a message as soon as you leave the

TextBox

. It should also refuse to let you submit the form to the server.

As pointed out before, this is not entirely useful in itself; for the rare occasions you would use this, you would not mind hacking the

RequiredFieldValidator

to do your bidding.

Only when you start considering the combinations of the unique properties listed above do you realize how powerful this is.

ControlToCompare

Instead of comparing a control with a literal value, you can compare it to another user-entered string. You do this by pointing the

.ControlToCompare

property to the control you wish to validate.

If this and

.ValueToCompare

are both set,

.ValueToCompare

will be ignored.

Operator

It is not only possible to compare values for equality (or inequality), it is possible to look for

GreaterThan

,

GreatThanEqual

,

LessThan

or

LessThanEqual

.

In all cases, if the condition is true then the

.ControlToValidate

is considered valid.

Alternatively, you can even check that the input data can be converted to a certain type, using the

DataTypeCheck

value in this property. This is essential, as pointed out above, because a comparison including an invalid value will always be treated as valid.

For example, when comparing two dates, if “F” is compared to “01/01/2003″ then it is simultaneously considered to be greater than, less than

and

equal to. But when checking “F” using a

CompareValidator

where

.Operator = DataTypeCheck

and

.Type = Date

, validation will fail.

When using

.Operator = DataTypeCheck

, the

.ValueToCompare

and

.ControlToCompare

properties are both ignored and the

.Type

property is used to define the valid type.

The RangeValidator

The

RangeValidator

is much like the

CompareValidator

control (hence the common base class), except that it verifies that the user data falls between two constant values, rather than comparing it to a single value (constant or variable).

With that in mind, the control’s unique properties (not part of

BaseCompareValidator

) are much as you might expect.


.MaximumValue
Value may not be greater than this.

.MinimumValue
Value may not be less than this.

Example

Referring to our simple form, we can easily use a

RangeValidator

to verify that the email address entered begins with a lower-case alpha character. Of course, this is not much validation for an email address, but it is a good demonstration of the

RangeValidator

.

Replace whichever validator you are using with a

RangeValidator

, set the

.ControlToValidate

and

.ErrorMessage

as for any validator. Then set

.MinimumValue

to

a

and

.MaximumValue

to

z

.

Now any string entered that begins with a lower-case alpha character will be considered valid. Note again that if the

TextBox

is left blank, it is still considered valid. A separate

RequiredFieldValidator

must be used if the field is mandatory.

MaximumValue

The value entered by the user may not be greater than this, but the two values can be equal.

MinimumValue

The value entered by the user may not be less than this value (unless blank), but the two values can be equal.

The RegularExpressionValidator

Arguably the biggest, most versatile weapon in the ASP.NET validation arsenal has to be the

RegularExpressionValidator

.

With just one custom property over those provided by the

BaseValidator

class, a world of options become available.


.ValidationExpression
Value must be in the format described.

Example

In our simple example, replace the current validator with a

RegularExpressionValidator

and set the

.ControlToValidate

and

.ErrorMessage

as usual.

Set the

.ValidationExpression

to

\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

. If you are using Visual Studio .NET, you can click the ellipses (…) button alongside the property and select

Internet Email Address

from the default list.

Whilst not perfect email address validation (see below), this is a pretty good approximation. It ensures that the address consists only of “word” characters (A-Z,a-z,0-9,_) with

exactly

one @ symbol and at least one period (.) after it, allowing for variations which include hyphenations in mid-word and extra periods before and after the @ symbol.

Again, notice that a blank field is always valid unless you also use a

RequiredFieldValidator

. And, as with all validation controls, no code is required to perform an identical validation on both the Client and the Server.

ValidationExpression

The data entered, if not blank, must match the format specified in regular expression format.

This article will not attempt to cover regular expressions in detail, much has been written elsewhere on this site and others on this subject.

Frankly, I do not claim to understand it that well, I usually manage with the default values provided by Visual Studio .NET or others that I find through Google (there are some fascinating expressions out there, if you look hard enough).

The Visual Studio .NET default values can be found via the ellipses (…) button to the right of the property (within the property sheet) and offer the following validations:


  • US / French / German / Japanese / PRC Phone Number

  • US / French / German / Japanese / PRC French Postal Code

  • US / PRC Phone Number

  • Internet Email Address

  • Internet URL

There are some surprising omissions here (certain nationalities, US State Abbreviations, ISBN, Credit Cards, Long Date Formats), and some of the default expressions (inc. Email address) are not 100% accurate.

The

Regular Expression Library

is the best resource I have found for most of those that are missing and for improving those that exist.

If anyone has other resources, I would be happy to list them with the next update.

The CustomValidator

Sooner or later (probably later, to be honest), you are going to need to validate something and the standard validators are not going to offer it. Maybe you need to access a database, or perform some complex validation involving numerous controls.

If you are going to need to do it repeatedly, you might want to consider creating your own validation control, but for the one-off oddity you can use the

CustomValidator

.

The

CustomValidator

allows you to add code to be run on the client and / or the server and set a value showing the result.

You can populate the

.ControlToValidate

property, passing the value of the control to the event handler or script. But, unlike the other validation controls, the

CustomValidator

will not throw an exception if

.ControlToValidate

is empty.

Other than that, it acts exactly the same as any other validation control, either showing the

.ErrorMessage

in the control itself or passing it to a

ValidationSummary

control.

The

CustomValidator

has only one unique property and a unique event handler.


.ClientValidationFunction
Name of HTML-scripted function to execute, on validation

.ServerValidate
Event handler for server-side validation.

Example

Using our simple example once more, replace the validation control with a

CustomValidator

. Set the

.ControlToValidate

and

.ErrorMessage

properties as before. Ignore the

.ClientValidationFunction

property for now and add an event handler for the

.ServerValidate

event.

You can validate the value entered against a database, if you wish. For simplicity, I have chosen to simulate this with a simple

if

statement.

private void alreadyInUse_ServerValidate(object source, System.Web.UI.WebControls.ServerValidateEventArgs args){ // Default Value args.IsValid = true; // Simulating a check against a database if (args.Value == "pdriley@santt.com") args.IsValid = false;}

The validator will always post back to the server to the

ClickEvent

handler which the requests the results of the validation. But if you enter one of the “existing” E-mail addresses (in my case, my own address) then the error message will be reported back and the

Response

will not be redirected.


NOTE:

The

ServerValidate

event itself, in fact all server-side validation, is executed after the

Page_Load

event and before any other events. But the result of the validation is irrelevant unless you later check that the form is valid. The

Button_Click

event, in this case, is still executed.

ServerValidate (Event)

As you can see in the example above, the

ServerValidate

event handler should accept an object (the

CustomValidator

) and arguments of type

ServerValidateEventArgs

.

The

ServerValidateEventArgs

class exposes two properties:

.IsValid

and

.Value

. All you have to do in most cases is check that

.Value

is valid and set

.IsValid

accordingly.

If there is no

.ControlToValidate

property set for the

CustomControl

then

args.Value

will default to

String.Empty

, but you can still validate the values contained in the controls.

ClientValidationScript

Writing a JavaScript handler is conveniently similar to writing the server-side handler. It still exposes the same two arguments,

source

and

args

.

The sample C# code above would directly translate as:

 function 
alreadyInUse_Validate (source, args){
 // 
 Default Value 
args.IsValid =
 true 
;
 // 
 Simulating a check against a database 
 if 
(args.Value ==
 " 
 pdriley@santt.com" 
) args.IsValid =
 false 
;}

All that is left to be done is set the

.ClientValidationScript

property to

alreadyInUse_Validate

and the client-side validation is complete.

The ValidationSummary

It should be fairly clear by now that many web pages are going to include a lot of validation controls. No user is going to be happy with all those error messages popping up at random positions around the page, but it is always nice to have something marking the invalid fields.

And this is where the

ValidationSummary

control comes into play.

The

ValidationSummary

derives directly from

WebControl

and is not related to the other controls except by symbiotic functionality.

When a page is validated, all of the

.ErrorMessage

properties from validation controls in the same container (e.g..

Form

or

DataGrid

row) that fail validation are passed to the

ValidationSummary

control to be displayed in an unordered list.

This finally explains the

.Text

property, common across the validation controls. If

.Text

is populated then it will be displayed in place of the validation control, but still

.ErrorMessage

will be used to populate the

ValidationSummary

.

The

ValidationSummary

control has a number of unique properties that affect the way messages are displayed to the user.


.DisplayMode
How the unordered list is rendered.

.EnableClientScript
Should the error list be updated during client validation?

.HeaderText
Defines the text that heads the error list.

.ShowMessageBox
Show error message list in a javascript “alert”.

.ShowSummary
Render the error messages on the page itself.

Example

To demonstrate the full power of the

ValidationSummary

, it is necessary to come up with something a little more complicated than the simple example that is used throughout the rest of the article.

Consider a simple registration form for, say, a chat room.

The customer requesting this form has asked for the following:

  • User ID – mandatory, must be 6-8 characters
  • Password – mandatory, must be 8 characters with at least two numeric, also confirmed
  • Name – mandatory
  • E-mail – mandatory, must be valid format
  • Sex – mandatory, drop down list, must not default
  • Date of birth – not mandatory but must be valid if entered

Set the form up yourself, complete with validators, using the rest of this article as a guide. As well as giving each control an error message, change the

.Text

properties to

*

and drop the new (much smaller) control next to the control it is validating.

Although the Visual Studio .NET IDE will not allow you to drop validation controls directly on top of each other, you can edit the HTML view to force the controls into the same position.

Along with the diagram, here is a clue: there are 12 validation controls in total:

  • 6 x

    RequiredFieldValidator
  • 4 x

    RegularExpressionValidator
  • 2 x

    CompareValidator

Drop a

ValidationSummary

at the bottom of the page, next to a submit button. The only property you might want to set is the

.HeaderText

. (In the example, it is set to

Please fix the following errors:

)

Run the form and you can now see how a combination of validation controls and a

ValidationSummary

control can be used to create a very secure and yet flexible and most importantly usable Web Form.

If you get stuck then, again, the example is included in the downloadable zip file at the top of the article.

DisplayMode

The list can be rendered in any of the following

DisplayMode

styles:


  • BulletList

    (list items in an unordered list)

  • List

    (delimited only by a new line)

  • SingleParagraph

    (delimited by space)

The default option is

BulletList

.

EnableClientScript

By default,

.EnableClientScript

is

true

and the list of errors will be shown when the form is submitted.

If

.EnableClientScript

is set to

false

then the

ValidationSummary

will not be shown until the server reports the errors back to the client machine.

This is useful if (and only if) the

.EnableClientScript

property of all the validation controls are also

false

. If they are not then the form will not post back to the server and the

ValidationSummary

will never report the errors.

HeaderText

Allows the definition of text to describe the list of errors. This will be posted directly before the list of error messages, regardless of the

.DisplayStyle

value.

ShowMessageBox

If set to

true

, the

ShowMessageBox

property creates a JavaScript,

alert()

call to display all of the error messages in a message box.

The message box will emulate the style defined in

.DisplayMode

as closely as possible.

ShowSummary

If set to

true

, the

ShowSummary

property renders the list of error messages into the HTML at the position of the

Label

.

Either

ShowMessageBox

or

ShowSummary

should always be

true

, but they should only both be true if absolutely necessary.

Bypassing validation

If you have two postback events (e.g.. “Next” and “Back” buttons), and one requires validation while the other does not, you can set the

.CausesValidation

property of one control to

true

and the other to

false

.

This will bypass both client and server validation. You can still check

this.IsValid

, if you want to use some common code for handling both events, and validation will succeed even if there is no valid data entered.

Conclusion

This is a very powerful set of controls with very few obvious dangers. As an added bonus, they are incredibly easy to implement. In Visual Studio .NET, it is just drag-drop and select a couple of properties.

There is a lot of information to absorb in one pass, but hopefully this article will serve as a reasonably simple reference guide as well as a “How to” guide.

Once you have used the validation controls a few times, you will be dropping them into pages just for fun.


ASp.net Charts

Introduction

Microsoft has just launched a very rich chart control for .NET web and Windows Forms applications. Let’s take a look at some features from it.

Chart Types

The following chart types are available:

  • Bar and columns
  • Line
  • Area
  • Pie and Doughnut
  • Point
  • Range
  • Circular
  • Accumulation
  • Data Distribution
  • Financial

You still have the option to combine more than one chart type.

Bind Types

The following options are available to be used as bind types for your application charts:

  • XML Files
  • Excel Files
  • CSV Files
  • Arrays
  • IEnumerable objects
  • Dataviews

How To…

The examples and documentation are really good and to work with the new Microsoft Chart control is very straightforward. Drag and drop a chart control, set properties in design and / or runtime and it’s done!

Namespace

The namespace you are going to use is System.Web.UI.DataVisualization.Charting.

Main Properties

  • ChartAreas: It is the area where a chart is plotted. Your chart may contain more than one chart area, that means you may plot more than one chart by render and you may even overlap charts.
  • Series: It is the data you may plot on your chart area.
  • ChartType: The chart type property is under the Series property and defines how your data series will be displayed on a chart area.
  • Axes: Defines properties for the X and Y axes like appearance and titles.
  • Palette: Defines the colors set for your chart.
  • Titles: Defines text that may be used to describe a chart, an axis or any other part of the chart.
  • Legends: Defines the legends that will display the data series information.
  • Labels: Defines text that may be displayed close to axis, points and custom labels.

  • Categories

  • Quick Contact
    Copyright © 1996-2010 AXAT Technologies. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress