Introduce DataBase,Asp.net,JavaScript,Xml,Html,Css,Sql,Php,ASP.NET Controls,AJAX,Tools,HTML,CSS,JavaScript,Open Source Project,WPF,.Net Framework,Linq
Top Recommended Hosting

Use .NET Validation

by the3factory 5/7/2008 5:18:00 AM

User input can come from a variety of locations: You must test input from data files as well as interactive controls. Writing user input validation is pedantic and error-prone but very necessary. Trusting user input can cause anything from exception conditions to SQL injection attacks. None of the options is pleasant. You know enough to be very skeptical of the validity of user input. Good. So does everyone else. That's why the .NET Framework has extensive capabilities that you can use to minimize the amount of code you need to write, yet still validate every piece of data that your users give you.

The .NET Framework provides different mechanisms to validate user input for web- and Windows-based applications. Web applications should get data validated at the browser, using JavaScript. The validation controls generate JavaScript in the HTML page. It's more efficient for your users: They do not need to have round-trips back to the server each time they change an entry. These web controls make extensive use of regular expressions to tentatively validate user input before the page is posted back to the server. Even so, you'll want to perform more extensive validation at the server, to prevent programmatic attacks. Windows applications use a different model. User input can be validated in C# code that runs in the same context as the application. The full gamut of Windows controls is available to you when you want to notify the user of invalid input. The general model uses exceptions in property accessors to indicate the invalid input. UI widgets catch those exceptions and display errors to the user.

You can use five web controls to handle most of the validation tasks in your ASP.NET applications. All five are controlled by properties that specify the field that should be validated and the conditions for valid input. RequiredFieldValidator forces the user to enter some value in a given field. RangeValidator mandates that a specific field supplies a value within a given range. This range could be the magnitude of a number or the length of a string value. CompareValidator lets you construct validation rules that relate two different fields in a web page. These three are relatively simple. The last two give you all the power you need to validate almost any user input you are expecting. The RegularExpression validator processes the user input using a regular expression. If the comparison returns a match, the user input is valid. Regular expressions are a very powerful language. You should be able to create a regular expression for any situation you have. Visual Studio .NET includes sample validation expressions that help get you started. There is a wealth of resources to help you learn all about regular expressions, and I strongly encourage you to do that. But I can't leave this topic without giving you a few of the most common constructs. Table 5.1 shows the most common regular expression elements you'll use for validating input in your applications.

Table 5.1. Common Regular Expression Constructs

Construct

Meaning

[a-z]

Matches any single lowercase letter. Anything inside square brackets matches a single character in the set.

\d

Any digit.

^,$

^ is the beginning of the line, and $ is the end.

\w

Matches any "word" character. It is shorthand for [A-Za-z0-9].

(?NamedGroup\d{4,16})

Shows two different common elements. ?NamedGroup defines a variable that references the match. {4,16} matches the preceding construct at least 4 times but no more than 16. This pattern matches a string of at least 4 but no more than 16 digits. If a match is found, the match can be referred to later as NamedGroup.

(a|b|c)

Matches any of a, b, or c. Options separated by vertical bars are ORed: The input string can contain any one of them.

(?(NamedGroup)a|b)

Alternation. This is the equivalent of the ternary operator in C#. It means "If NamedGroup exists, match a, else match b."


Using these constructs and regular expressions, you will find that you can validate just about anything that your users throw at you. If regular expressions aren't enough for you, you can add your own validator by deriving a new class from CustomValidator. This is quite a bit of work, and I avoid it whenever I can. You write a server validator function using C#, and then you also write a client-side validator function using ECMAscript. I hate writing anything twice. I also avoid writing anything in ECMAscript, so I like to stick to regular expressions.

For example, here is a regular expression that validates U.S. phone numbers. It accepts area codes with or without parentheses around them, as well as any number of whitespace between the area code, exchange, and number. A dash between the area code and the exchange is also optional:

((\(\s*\d{3}\s*\))|(\d{3}))-?\s*\d{3}\s*-\s*\d{4}

By examining each group of expressions, the logic is clear:

((\(\s*\d{3}\s*\))|(\d{3}))-?

This matches the area code. It allows either (xxx) or xxx, where xxx is three digits. Any amount of whitespace surrounding the digits is acceptable. The last two characters, - and ?, allow but do not demand a dash.

The remaining portion matches the xxx-xxxx portion of the phone number. \s matches any amount of whitespace. \d{3} matches three digits. \s*-\s* matches a dash surrounded by any number of whitespace. Finally, \d{4} matches exactly four digits.

Windows validation works somewhat differently. No precooked validators parse input for you. Instead, you need to write an event handler for the System.Windows.Forms.Control.Validating event. Or, if you are creating your own custom control, override the OnValidating method (see Item 35). A standard form for a validation event handler follows:

private void textBoxName_Validating( object sender,
System.ComponentModel.CancelEventArgs e )
{
string error = null;
// Perform your test
if ( textBoxName.Text.Length == 0 )
{
// If the test fails, set the error string
// and cancel the validation event.
error = "Please enter a name";
e.Cancel = true;
}
// Update the state of an error provider with
// the correct error text. Set to null for no
// error.
this.errorProviderAll.SetError( textBoxName, error );
}

You have a few more small tasks to make sure that no invalid input sneaks through. Every control contains a CausesValidation property. This property determines whether the control participates in validation. In general, you should leave it true for all of your controls, except for the Cancel button. If you forget, the user must create valid input to cancel from your dialog box. The second small task is to add an OK handler to force validation of all controls. Validation happens only when a user visits and leaves a control. If the user opens a form and immediately presses OK, none of your validation code executes. To fix that, you add an OK button handler to walk through all your controls and force them to validate. The following two routines show you how to do this correctly. The recursive routines handle those controls that are also containers for other controls: tab pages, group boxes, and panels:

private void buttonOK_Click( object sender,
System.EventArgs e )
{
// Validate everyone:
// Here, this.DialogResult will be set to
// DialogResult.OK
ValidateAllChildren( this );
}
private void ValidateAllChildren( Control parent )
{
// If validation already failed, stop checking.
if( this.DialogResult == DialogResult.None )
return;
// For every control
foreach( Control c in parent.Controls )
{
// Give it focus
c.Focus( );
// Try and validate:
if (!this.Validate( ))
{
// when invalid, don't let the dialog close:
this.DialogResult = DialogResult.None;
return;
}
// Validate children
ValidateAllChildren( c );
}
}

This code handles most normal cases. A special shortcut applies to the DataGrid/DataSet combination. Assign the ErrorProvider's DataSource and DataMember properties at design time:

ErrProvider.DataSource = myDataSet;
ErrProvider.DataMember = "Table1";

Or, at runtime, call the BindToDataAndErrors method to set both in one operation:

ErrProvider.BindToDataAndErrors(
myDataSet, "Table1" );

Errors get displayed by setting the DataRow.RowError property and calling the DataRow.SetColumnError method to display specific errors. The ErrorProvider displays the red exclamation icon on the row and the specific cell in the DataGrid.

This whirlwind tour of the validation controls in the framework should help you efficiently create the validation you need in many applications. User input cannot be trusted: Users make mistakes, and occasionally malicious users try to break your application. By making the most use of the services already provided by the .NET Framework, you reduce the code you need to write. Validate all user input, but do it efficiently with the tools already provided.

Related posts

Sign up for PayPal and start accepting credit card payments instantly.


Powered by BlogEngine.NET 1.2.0.0