|
This article shows how you can take advantage of the validation features within the Validation Application Block,
part of version 3.0 of Enterprise Library, in your ASP.NET applications. The block supports both UI and object
validation, and you can combine these approaches using the same rules if you wish. The ability to validate
objects is particularly useful when working with instances that may be generated locally, exposed by other
tiers of your application, or received from a remote Web Service.
Contents
Validating Objects from Other Sources
To demonstrate how useful the Validation Application Block is, and how you can use a rule set to
validate object instances wherever they originate from, the example application contains a simple
Web Service that returns populated instances of a class compatible with the
CompanyDetails target class.
The Example Web Service
The Web Service project, named SampleWebService, uses the following code to expose
two Web Methods. The GetValidCompanyInstance method returns an object with valid
property values, and the GetInvalidCompanyInstance method returns an instance with
invalid values for all of the properties:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using EntLibSamples;
[WebService(Namespace = "http://www.daveandal.net/articlesamples/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class CustomerService : System.Web.Services.WebService
{
[WebMethod]
public EntLibSamples.CompanyDetails GetValidCompanyInstance()
{
// create sample object instance and set properties
EntLibSamples.CompanyDetails companyObject
= new EntLibSamples.CompanyDetails();
companyObject.CompanyName = "FooBar Trading Company";
companyObject.CompanyAddress = "123, The Industrial Estate";
companyObject.CompanyCity = "Manchester";
companyObject.CompanyPostalCode = "12345-1234";
companyObject.EmployeeCount = 12;
companyObject.LastReportDate = new DateTime(2007, 03, 03);
return companyObject;
}
[WebMethod]
public EntLibSamples.CompanyDetails GetInvalidCompanyInstance()
{
// create sample object instance and set properties
EntLibSamples.CompanyDetails companyObject
= new EntLibSamples.CompanyDetails();
companyObject.CompanyName = "Foo";
companyObject.CompanyAddress = "Bar";
companyObject.CompanyCity = "A really long city name that "
+ "exceeds the validation limit";
companyObject.CompanyPostalCode = "England";
companyObject.EmployeeCount = 0;
companyObject.LastReportDate = new DateTime(2002, 10, 10);
return companyObject;
}
}
You can see that the Web Service references the EntLibSamples namespace, and
creates instances of the example CompanyDetails class from that namespace.
However, as you will see shortly, you still need to convert the object exposed by the Web
Service to the correct type for validation.
Validating Objects from the Example Web Service
The code-behind file for the Default.aspx page in the main Web site contains code
to access the example Web Service to obtain instances of the target class that it can validate and
display. However, although the Web Service returns an object compatible with the
CompanyDetails class defined in the configuration, it is not directly convertible.
Therefore, the code contains a simple routine that creates a new instance of the local
EntLibSamples.CompanyDetails class, and then copies to it the property values from the
SampleService.CompanyDetails instance returned by the Web Service:
private EntLibSamples.CompanyDetails ConvertServiceObject(
SampleService.CompanyDetails serviceObject)
{
// generate local CompanyDetails object from the values
EntLibSamples.CompanyDetails companyObject
= new EntLibSamples.CompanyDetails();
companyObject.CompanyName = serviceObject.CompanyName;
companyObject.CompanyAddress = serviceObject.CompanyAddress;
companyObject.CompanyCity = serviceObject.CompanyCity;
companyObject.CompanyPostalCode = serviceObject.CompanyPostalCode;
companyObject.EmployeeCount = serviceObject.EmployeeCount;
companyObject.LastReportDate = serviceObject.LastReportDate;
return companyObject;
}
The handlers for the Create a Valid Company using a Web Service
and Create an Invalid Company using a Web Service buttons start
by creating a reference to the Web Service, and then call the relevant method to
get the new object instance. Then they can convert the object to the relevant type
using the routine just described, and pass it to the DisplayAndValidateSampleObject
method (described earlier) for validation and display.
For example, this is the code in the Create a Valid Company... button handler:
// get valid sample object instance from Web Service
CustomerService service = new CustomerService();
SampleService.CompanyDetails serviceObject
= service.GetValidCompanyInstance();
// generate local CompanyDetails object from the values
EntLibSamples.CompanyDetails companyObject
= ConvertServiceObject(serviceObject);
// display and validate property values
DisplayAndValidateSampleObject(companyObject);
Figures 6 and 7 show the results when you click the Create a Valid Company using a Web Service
and Create an Invalid Company using a Web Service buttons in the example application.

Figure 6 - The result of validating an object obtained from a remote Web Service with valid property values when you click the "Create a Valid Company using a Web Service" button

Figure 7 - The result of validating an object obtained from a remote Web Service with invalid property values when you click the "Create an Invalid Company using a Web Service" button
UI Validation Integration in ASP.NET
The Validation Application Block contains UI validation integration features for both Windows Forms and
ASP.NET applications. Of course, both of these environments already include built-in UI validation
controls and features; however the capability for integrating validation across both the UI and object
instances within an application is extremely useful. For example, as you will see in the example application,
you can use a common rule set for validation of both UI and objects.
The example application contains a drop-down list where you can turn on and off UI validation for
controls in the page. If you set this option to enabled, and then create and validate an object
instance, you will see that the page displays the error messages next to each text box, and does not actually
create a new object for validation (see Figure 8). Instead, it displays a message indicating that validation
errors occurred.

Figure 8 - The result of validating the proposed values for the properties of the sample object when ASP.NET integration is enabled
The PropertyProxyValidator Control
ASP.NET integration uses a class named PropertyProxyValidator, which implements a
control that you can use within an ASP.NET Web page to perform UI validation. This control inherits
from the ASP.NET validation control base class named BaseValidator, and is therefore effectively an
ASP.NET validation control.
The BaseValidator class exposes properties such as ControlToValidate,
Display (None, Static, Dynamic),
EnableClientScript, Enabled, IsValid,
SetFocusOnError, and ValidationGroup. However, many of these are set
within the PropertyProxyValidator class, although - as you will see
- you can also set them yourself in code, or with attributes within
the control declaration on an .aspx page.
The PropertyProxyValidator class also exposes the Validate method,
which you can use to initiate validation of specific validators if required.
However, all the instances of the PropertyProxyValidator class you place in
a page integrate with the ASP.NET validation system, and so you can cause
validation by calling the Validate method of the Page class, and check
the result using the IsValid property of the Page class.
Note: You must call the Page.Validate method, or the Validate
method of individual validation controls, to validate submitted values when using the
PropertyProxyValidator class. This does not occur automatically.
To use the PropertyProxyValidator class, you simply add instances to the
ASP.NET page, either by declaring them within the .aspx file or by
generating instances dynamically at runtime and adding them to the Controls
collection of the Page object or another container control.
The process is identical to adding ASP.NET built-in validation controls such as the
RequiredFieldValidator or any other ASP.NET control) to a page.
The only real differences when working with the Validation Application Block compared to
the ASP.NET validation controls are:
-
You must include an @Register directive in the ASP.NET page to
register the integration assembly that contains the PropertyProxyValidator control:
<%@ Register Assembly="Microsoft.Practices.EnterpriseLibrary
.Validation.Integration.AspNet"
Namespace="Microsoft.Practices.EnterpriseLibrary
.Validation.Integration.AspNet"
TagPrefix="EntLibValidators" %>
You use only one type of validation control, the PropertyProxyValidator control, for all validation operations. The actual operation and parameters appear in the configuration file or in attributes applied to the target object class and its members. You should have a target object class defined that supports validation through configuration or attributes.
You specify the name of the rule set, the type name of the target object, and the target object member (method or property name) in the PropertyProxyValidator control declaration. For example:
<EntLibValidators:PropertyProxyValidator ID="CompanyNameValidator"
runat="server" ControlToValidate="txtName"
PropertyName="CompanyName" RulesetName="ExampleRuleSet"
SourceTypeName="EntLibSamples.CompanyDetails" />
-
You may need to convert the values obtained from the input control to a suitable type if the
.NET default type conversion mechanism cannot automatically convert the type.
Create a handler for the ValueConvert event of the validation control
that accepts a ValueConvertEventArgs instance, convert the object passed
as the ValueToConvert property of this instance to the appropriate type,
then return it as the ConvertedValue property. If conversion is not valid,
set the ConversionErrorMessage property to a suitable error message.
However, for most simple value types, this is not required.
-
The PropertyProxyValidator control does not appear in the Visual Studio
2005 Toolbox by default. However, you can add it to the General section of
the Toolbox by opening the Choose Items dialog, browsing to the
Microsoft.Practices.EnterpriseLibrary.Validation.Integration.AspNet.xml assembly, and placing
a tick next to PropertyProxyValidator in the list of Toolbox components.
Figure 9 shows how Visual Studio 2005 displays the PropertyProxyValidator control in Design view.

Figure 9 - The Default.aspx page of the example application in Design view showing the PropertyProxyValidator controls
Implementing UI Validation in the Example Application
The first step in adding Validation Block integration with ASP.NET is to declare the
PropertyProxyValidator controls for each UI input control. This is
simply a matter of dragging the control from the Toolbox (if you have installed it there)
onto the page in Design view, or typing and then pasting and copying the declaration in
Source view. Also remember that you must add the appropriate @Register directive to the
page as well, as described in the previous section of this article.
For each validated UI input control, specify that input control's ID property
as the ControlToValidate property of the PropertyProxyValidator control.
Also set the RulesetName, SourceTypeName, and PropertyName
properties to the appropriate values based on your application configuration.
You can view the Default.aspx page in the example application to see the final result.
Validating the UI Control Values
To validate the UI control values, add code to the handler for the button or other control that submits the page.
The example application checks the Page.IsValid property, and - if it True -
creates an instance of the target object and displays its property values in the page. A separate routine named
CreateLocalCompanyObject performs the task of applying the validated UI values to a new instance
of the target object, and displaying its properties in the page:
// force validators to check control values
Page.Validate();
if (Page.IsValid)
{
// create sample object instance and set properties
CreateLocalCompanyObject();
}
else
{
lblResult.Text = "Validation errors encountered by ASP.NET "
+ "Integration Validators<p />";
}
You saw the CreateLocalCompanyObject routine used (and described) in the earlier section of
this article "Validating Object Instances". As well as creating the new object instance and
displaying the property values, this routine performs object-level validation by calling the static Validate
method of the Validation Application Block.
Note: It is always a good idea to repeat on the server any UI validation you carry
out before using posted values in your application. This protects against spoofing attacks; and
against issues that may arise is client browsers do not fully support or correctly process
client-side script. However, unlike the ASP.NET validation controls, the
PropertyProxyValidator controls only perform validation
server-side, and not through client-side script.
Accessing PropertyProxyValidator Controls in Code
One other features of the example application is the ability (as you have seen) to enable
and disable UI integrated validation. The code to achieve this demonstrates a useful
technique that you can take advantage of to change the behaviour of some or all
instances of the PropertyProxyValidator control in your pages.
The Default.aspx page contains a drop-down list that defines two values:
"disabled" (value = False)
and "enabled" (value = True):
<asp:DropDownList runat="server" ID="lstEnableIntegration">
<asp:ListItem Text="disabled" Value="false" />
<asp:ListItem Text="enabled" Value="true" />
</asp:DropDownList>
The example application also contains code in the handler that executes in response to
the Page.Load event. This code iterates through all the instances of
PropertyProxyValidator controls on the page, setting the Enabled
property to that specified in the drop-down list control. Notice that it accesses each validation
control using the IValidator interface (from the System.Web.UI namespace), which
means that the code will work in a page that contains built-in ASP.NET validation controls as well
as PropertyProxyValidator controls:
protected void Page_Load(Object sender, System.EventArgs e)
{
// set the Enabled property for every EntLib Validator control
foreach (IValidator validatorControl in Page.GetValidators(null))
{
if (validatorControl is PropertyProxyValidator)
{
PropertyProxyValidator ctrl
= (validatorControl as PropertyProxyValidator);
ctrl.Enabled = Boolean.Parse(lstEnableIntegration.SelectedValue);
}
}
}
Note: If you have defined validation groups for the validators in your page,
you can select just the validation controls in that group using the single parameter of the
Page.GetValidators method. See the ASP.NET documentation for details of
using validation groups in ASP.NET.
The code checks if each validator it finds is of type PropertyProxyValidator, and - if it is -
casts the reference to the PropertyProxyValidator type so that it can set the Enabled
property to the value selected in the drop-down list. You can use this technique to set the properties of any type of
validation control.
The Visual Basic.NET equivalent of the Page.Load routine, showing the different syntax for
converting the validator control reference, is:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' set the Enabled property for every EntLib Validator control
For Each validatorControl As IValidator In Page.GetValidators(Nothing)
If TypeOf validatorControl Is PropertyProxyValidator Then
CType(validatorControl, PropertyProxyValidator).Enabled _
= Boolean.Parse(lstEnableIntegration.SelectedValue)
End If
Next
End Sub
One final twist to the code in the example application is that, when UI validation integration is enabled, it only creates the target object instance and performs server-side validation of the property values if the UI validation does not detect any validation errors. The actual code used in the example application is:
// check if user has turned on ASP.NET client-side integration
if (lstEnableIntegration.SelectedValue == "true")
{
// force validators to check control values
Page.Validate();
if (Page.IsValid)
{
// create sample object instance and set properties
CreateLocalCompanyObject();
}
else
{
lblResult.Text = "Validation errors encountered by ASP.NET "
+ "Integration Validators<p />";
}
}
else
{
CreateLocalCompanyObject();
}
Summary
This article discussed how you can take advantage of the Enterprise Library Validation Application Block in ASP.NET applications, concentrating on the use of rule sets that allow validation across the UI and object instances within the application tiers (and, if required, in Windows Forms applications as well).
While ASP.NET provides a fully-featured set of UI validation controls, these do not always fulfil the requirements of enterprise-level applications. The Validation Application Block supports a wider range of validators, has features to allow composition and negation of validators, and supports validation using configuration rules as well as attributes applied directly to classes and class members.
In the example application that accompanies this article, you can see how easy it is to use the Validation Application Block and a rule set to validate local objects, object instances generated from calls to a remote Web Service, and UI input control values.
You can also combine the Validation Application Block validators with the ASP.NET built-in validators if required. The PropertyProxyValidator control that supports ASP.NET integration is itself a descendant of the ASP.NET validator base class, and so behaves and can be handled in the same way as the ASP.NET validation controls.
Having seen the capabilities it provides, you may wish to consider using the Validation Application Block to extend the validation capabilities of your code as you build applications that are ever more complex, and more highly distributed in nature.
Download the Source Code
You can download the source code presented in this article in zip file format from here:
070607.zip.
About the Author
Alex Homer is a freelance developer and writer, currently sending most of
his time working with Wrox Press Limited in the UK. Alex's own company,
Stonebroom Software, has been running - on and off and with a couple of
name changes - for some fifteen years while he held down a 'day-job' as
well. He started writing system utilities in assembler (machine code) which
were sold through a small distributor in Blackpool, the UK's 'silicon
beach' of home computing in the early eighties. Since then, development has
moved through Pascal in MS-DOS, Delphi and Visual Basic in Windows, and now
to the Internet in general. Having worked in the Glass and Glazing industry
for some years, Alex also develops vertical market software aimed at making
the specifier's and estimator's job easier. They still think Windows are
things you lean out of.
|