Delen via


The Validation Application Block

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The latest Enterprise Library information can be found at the Enterprise Library site.

patterns & practices Developer Center

On this page:
Supported Scenarios - Defining Validation Rules Using Attributes, Supported Validators | Comparing WCF RIA Services' Validation to the Validation Application Block | Changes to Enterprise Library 5.0 | Performing Cross-Tier Validation Using the Validation Application Block - Sharing Validation Rules Using Linked Files, Using Business Entities as Data Transfer Objects in WCF, Using Partial Classes Or Conditional Compilation, Sharing Validation Rules Using WCF RIA Services, Sharing Validation Rules Using Configuration | Using the Validation Application Block in a WCF RIA Services Application - When WCF RIA Services Triggers Validation, When the Validation Application Block Triggers Validation, Limitations of the WCF RIA Services Default Code Generator, Object Validator Attribute and Object Collection Validator Attribute, Performing Server-Side Validation with Rule Sets Or Validation Rules Defined in Configuration | Using the Validation Application Block in a WCF Data Services Application - Using the Metadata Type to Define Validation Rules, Performing Server-side Validation

The Enterprise Library Validation Application Block provides useful features that allow developers to implement structured and easy-to-maintain validation scenarios in their applications.

The Validation Application Block has been completely ported from Enterprise Library 5.0 to the Enterprise Library 5.0 Silverlight Integration Pack.

To learn more about the Validation Application Block, you can read more in the Developer's Guide or in the online documentation on MSDN®.

Supported Scenarios

The following scenarios are supported by the Validation Application Block from the Enterprise Library 5.0 Silverlight Integration Pack:

  • Execute validation rules and gather results. Using the Validator class, you can validate an object or graph of objects and gather the validation results.
  • Annotating your business entities with validation attributes. You can define validation rules by annotating your business entities with validation attributes, such as the StringLengthValidatorAttribute and the RangeValidatorAttribute.
    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed I prefer to define validation rules by annotating my business entities with validation attributes. This makes the validation rules easy to comprehend and maintain because the code is declarative and describes itself. And also, it's really easy to test your validation rules with unit tests. Since most validation rules don't change often, I can define most of my rules in code and only define them in configuration if they are likely to change often.
    - **Data annotations compatibility.** The validation attributes from Enterprise Library are compatible with WCF RIA Services. There are some limitations, which are described in the section on Using the Validation Application Block in a WCF RIA Services application. - **Defining validation rules in configuration.** Using the Validation Application Block, you can also define validation rules for your business entities in a configuration file written in XAML. - **Conditional validation using rule sets.** The Validation Application Block supports the concept of rule sets. A rule set is a name given to a group of validation rules. You can use rule sets to run a specific set of validation rules in specific situations. - **Implementing self-validation.** Some validation rules are hard to express using attributes or configuration. You can also define validation methods on your business entities that will be executed when your objects are validated. - **Defining validation attributes in metadata.** Silverlight doesn't support the **MetadataTypeAttribute**. In the .NET Framework, this attribute is used to define metadata classes with validation attributes for your generated business entities. The Validation Application Block provides an implementation of the **MetadataTypeAttribute** for Silverlight. - **IDataErrorInfo support.** You can use the **DataErrorInfoHelper** to implement **IDataErrorInfo** on your classes. There is no built-in support for **INotifyDataErrorInfo** or **INotifyPropertyInfo** in the Validation Application Block, but the Stock Trader V2 reference implementation contains several classes to help with implementing these interfaces.

    Defining Validation Rules Using Attributes

    The most common way to add (relatively simple) validation rules to your business entity is by adding validation attributes to its properties.

    The following code snippet shows two examples of adding validation rules through attributes:

    [RelativeDateTimeValidator(-1000, DateTimeUnit.Year, -18, DateTimeUnit.Year, MessageTemplate = "You must be 18 years or older to use this application.")]
    public DateTime DateOfBirth{ get; set }
    
    [NotNullValidator]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 0, RangeBoundaryType.Ignore, MessageTemplate = "The lastname is required")]
    public string LastName {get;set;}
    

    As you can see, it's possible to combine validation rules by combining several validators together.

    Supported Validators

    All of the validators that are supported in the desktop version of Enterprise Library are also available in the Enterprise Library 5.0 Silverlight Integration Pack.

    Attribute

    Description

    And Composite Validator

    This validator creates a composite validator. Validation requires that all the validators that make up the composite validator be true. For example, you can use the And composite validator to require that both the not null validator and the date time range validator be true.

    Contains Characters Validator

    This validator checks that the property contains any or all of the characters that are specified by the CharacterSet property.

    Date Time Range Validator

    This validator checks that a DateTime object falls within the specified range.

    Domain Validator

    This validator checks that a value is one of the specified values in a specified set. For example, it can check that a name is "Tom," "Dick," "Harry," or "George" or that an integer is 2, 3, 5, 7, or 11. If the set only contains one value, you can use this validator to check for equality.

    Enum Conversion Validator

    This validator checks that a string can be converted to a value in a specified enum type. For example, it can check that "Blue" can be converted to a value in the Color enumeration.

    Not Null Validator

    This validator checks that the value is not null (C#) or Nothing (Microsoft Visual Basic® development system).

    Object Collection Validator

    This validator checks that the object is a collection of the specified type and then invokes validation on each element of the collection.

    Note: This validator will throw an exception if used on a WCF RIA Services entity without specifying a rule set.

    Object Validator

    This validator causes validation to occur on an object reference. All validators defined for the object's type will be invoked, just as if the Validation.Validate method had been called on the object.

    Note: This validator will throw an exception if used on a WCF RIA Services entity without specifying a rule set.

    Or Composite Validator

    This validator creates a composite validator. Validation requires that at least one of the validators that make up the composite validator be true. For example, you can use the Or composite validator to require that the Not Null validator or the date time range validator be true.

    Property Comparison Validator

    This validator compares the value to be checked with the value of a property.

    Range Validator

    This validator checks that a value falls within a specified range.

    Regular Expression Validator

    This validator checks that the value matches the pattern specified by a regular expression.

    Relative Date Time Validator

    This validator checks that the DateTime value falls within a specified range using relative times and dates.

    String Length Validator

    This validator checks that the length of the string is within the specified range.

    Type Conversion Validator

    This validator checks that a string can be converted to a specific type. For example, the validator can check that "6.32" can be converted to a Double type or that "2007-02-09" can be converted to a DateTime type.

    If you'd like to learn more about applying validation attributes, please refer to 'Using Validation Block Attributes' in the Enterprise Library Documentation on MSDN.

    Comparing WCF RIA Services' Validation to the Validation Application Block

    WCF RIA Services is a technology that integrates the ASP.NET and Silverlight platforms. WCF RIA Services provide a pattern to write application logic that runs on the middle tier and controls access to data for queries, changes, and custom operations. It also provides end-to-end support for common tasks such as data validation, authentication, and roles by integrating with Silverlight components on the client and ASP.NET on the middle tier.

    There is quite a bit of overlap in the functionality of WCF RIA Services and the Validation Application Block when it comes to validation. For example, both provide a mechanism to add validation rules to business entities using attributes, both provide an API to trigger validation, and both provide mechanisms to notify the view of validation errors.

    This might seem a bit confusing, especially if you're trying to decide which technology to use in your application. While the Validation Application Block can be used standalone, it also works with and extends the validation support that WCF RIA Services provides with some more advanced scenarios. For example, the Validation Application Block also supports validation rules defined in configuration, or conditional validation rules by defining rule sets.

    While the Validation Application Block and WCF RIA Services work well together, there are some caveats you'll need to be aware of. These will be discussed in the section called Using the Validation Application Block in a WCF RIA Services application.

    If you wish to learn more about WCF RIA Services, please refer to the WCF RIA Services online documentation on MSDN.

    Changes to Enterprise Library 5.0

    The entire Validation Application Block has been ported from Enterprise Library 5.0 to the Enterprise Library 5.0 Silverlight Integration Pack. Several changes had to be made to Enterprise Library 5.0 for the desktop, to support:

    • Public properties on validation attributes. The WCF RIA Services code generator requires that the constructor parameters for all the validation attributes also have corresponding public read-only properties. These have been added.
    • The ToString method implemented on ValidationResult. The ValidationResult class now overrides the ToString method, which returns the message of the validation result. This allows you to use data binding to show the validation results in the user interface.
    • The DomainValidator attribute now has additional constructors. The DomainValidator attributeallows you tocheck a property value against an array of domain values. The WCF RIA Services code generator doesn't support generating attributes with arrays as constructor parameters. To overcome that, additional constructors were added that take up to 10 domain values.
    • The LowerBound and UpperBound properties’ types of the RangeValidator and DateTimeRangeValidator types changed to object. This was required to support the WCF RIA Services code generator.

    Performing Cross-Tier Validation Using the Validation Application Block

    A Silverlight LOB application typically consists of a Silverlight client that communicates with web services. To improve the user experience, you'll want to run as many validation rules as possible on the client. However, because it's possible to circumvent the client side validation logic, you should also perform the critical validation rules on the server.

    Duplicating the validation rules is not a good idea, because it's hard to keep them in sync. It's a better idea to define a validation rule in a single location and if required share it between the client and the server.

    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed While most validation rules can be executed both on the client and the server, there are some exceptions. Some validation rules can only be executed on the server; for example, checks for referential integrity. But there are also some validation rules which do not need to be executed on the server. For example, in the Stock Trader V2 application, we have implemented some validation rules as warnings. These validation rules are only intended to improve the user experience so they don't need to be executed on the server.

    The following diagram shows several options for sharing validation rules between the client and the server.

    Follow link to expand image

    In order to share validation rules between the client and the server, you'll need to have a common definition of the data to validate. Therefore, it's important to have a similar class definition for your business entity on the Silverlight client and on the server. Once you have that common basis, for example certain properties that are the same between Silverlight client's and server's business entities, it becomes possible to share validation rules as well.

    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed When you are sharing validation rules between the Silverlight client and the server, you will need to reference the Enterprise Library 5.0 binaries on the server, but reference the Enterprise Library 5.0 Silverlight Integration Pack binaries on the Silverlight client.

    There are several methods for sharing validation rules between the client and the server:

    1. Linked files
    2. WCF RIA Services code generation
    3. Configuration

    These options will be discussed further in the following sections.

    Sharing Validation Rules Using Linked Files

    One method for sharing code between a Silverlight and a non-Silverlight application is to use Microsoft® Visual Studio® development system linked files. This method can be used to share your validation rules, but also to share your class definition between client and server.

    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed We're applying this technique in the AccountHolder Module. We're using WCF Data Services to transfer data between client and server. On the server, we have created special metadata classes for our business entities which contain the validation rules. On the client, WCF Data Services has generated a proxy with the same business entities for us. We're then using Visual Studio linked files to also include the metadata classes in the Silverlight client.

    Normally, in Visual Studio all of your projects files are stored under the same folder as the project file itself. Using linked files, you can also use files that are stored outside of the project tree. This way, you can include a file that is physically in a different location.

    To add a linked file:

    1. In the solution explorer, open the project where you would like to add the linked file

    2. Right click and select Add existing file

    3. Browse to the file to add and using the drop-down box next to the add button, select Add as link as shown in the screenshot below:

      Hh852711.D143052CB90AB51DB8FAA376DB7C3AFB(en-us,PandP.51).png

    Of course, if you have decorated your business entities with validation attributes, you'll only have to share your class files with your business entities. If you have your validation logic stored in different classes, it's also possible to share those files.

    For more information on adding a linked file, please refer to MSDN.

    Using Business Entities as Data Transfer Objects in WCF

    If you are using linked files to share your business entities between the client and server, then it's often also possible to use your business entities as data transfer objects. This is a common approach for building Silverlight applications, since both the client and the server are based on Microsoft technologies.

    Note

    This technique should not be used if your web services need to be interoperable with non-Microsoft technologies. A Contract-first approach is then recommended to avoid interoperability issues.
    This technique is also not recommended if you have many different consumers of the same web service, because you're effectively exposing the internal structure of your application to the outside world. Any changes to your business entities will directly impact your client. This is not so much a problem if the client and the server effectively form a single application, but can become very difficult if you have many different consumers of the same web service. In that case, it's better to consider creating separate data transfer objects that can be versioned independently of the internal workings of your service.

    If you use business entities as data transfer objects in WCF services or WCF Data Services, then you must take special actions when creating a client proxy. The following diagram shows how this would work:

    Follow link to expand image

    Your web service application defines the business entities that may be decorated with validation attributes. By using the business entities in your service contracts, WCF will generate a WSDL with the type definitions for your business entities. In your Silverlight application, you'll need a web service proxy to access the application, which will be generated by Visual Studio. For regular WCF services, you can reuse the types in referenced assemblies. This means that the generated proxy uses your linked business entities, annotated with validation attributes, rather than generating business entities itself.

    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed Silverlight and the .NET Framework also allow for limited binary compatibility between Silverlight and .NET Framework assemblies. Initially we also looked at using this to share our business entities between client and server. Unfortunately, this would not work in our situation, because the enterprise library validation assemblies are not binary compatible. The business entities must reference these assemblies, because they use validation attributes to define validation rules, so the assemblies that that hold the business entities cannot be shared either.

    Using Partial Classes Or Conditional Compilation

    The linked code will be compiled for both the server and the Silverlight client. This means you can only use language constructs and other classes that are available on both platforms. By using partial classes or conditional compilation statements, you can add platform-specific code to your classes, but keep the shared file platform agnostic.

    Sharing Validation Rules Using WCF RIA Services

    One of the features of WCF RIA Services is the ability to share your business entities and their validation rules between the client and the server.

    WCF RIA Services typically revolves around an entity model. In your entity model, you design your business entities and how they map to database tables. Using a code generator, you'll be able to generate business entities on the server. Because the properties of these business entities are generated as well, you cannot directly add validation attributes to them. To solve this, WCF RIA Services allows you to add validation attributes to separate metadata classes. Both the WCF RIA Services and the Validation Application Block validation engines will also read validation attributes from these metadata classes. You can use both WCF RIA Services validation attributes and the Validation Application Block attributes to annotate the business entities or metadata classes.

    To share the business entities and their validation logic with the client, WCF RIA Services relies on a code generator. Any business entities on your server that are exposed through your business service will get a generated counterpart on the client. However, these classes don't use metadata classes to define their validation attributes, but get their validation attributes directly generated on their properties.

    Please refer to the chapter on Using the Validation Application Block in a WCF RIA Services application for more information.

    Sharing Validation Rules Using Configuration

    Another way you can share validation rules between the client and the server is by using configuration. If you wish to do so, both the client and the server need a common definition of your business entities. The class names, their namespaces, and the properties you wish to validate must be the same on both client and server. As described earlier, this can be achieved by using linked files or by using WCF RIA Services to share your business entities. However, if you use WCF Data Services or regular WCF services to generate a proxy for you, then the business entities generated for that proxy will typically be in a different namespace.

    Hh852711.note(en-us,PandP.51).gifSharon Says:
    Sharon If you wish to use validation rules defined in a configuration file, then you must trigger validation using the Validation Application Block Validator class. WCF RIA Services will not pick up any validation rules defined in configuration.

    On the server, you can define validation rules in the web.config file, for example by using the configuration console. The Validation Application Block will automatically read any validation rules defined in the web.config file.

    In Silverlight, you can define validation rules in a XAML configuration file that is either embedded in the XAP or downloaded from the server. This can be used to share validation rules between the client and the server, because you can generate XAML configuration files from the web.config file. For more information about the XAML generation process, please refer to the Configuration chapter.

    Hh852711.note(en-us,PandP.51).gifMark Says:
    Mark In Stock Trader V2, the web.config also contains Enterprise Library configuration that should not be converted to XAML, such as the logging and exception handling settings for the web server. To be able to share the validation rules between the client and the server, we decided to store the validation configuration in a separate file configuration source and only convert that file to XAML. The chapter on Configuration in the Stock Trader describes this process in more detail.

    Using the Validation Application Block in a WCF RIA Services Application

    The Validation Application Block works well with WCF RIA Services validation and can be used to extend WCF RIA Services with support for rule sets and validation rules defined in configuration. There are a couple of caveats to keep in mind, however.

    • Triggering Validation. Both WCF RIA Services and the Validation Application block provide a validator class that is used to trigger validation. Depending on which technology triggers the validation, you'll get slightly different behavior. We'll discuss these differences in more detail in this section.
    • RIA Services code generation. WCF RIA Services uses a code generator that reads the server-side business entities with their validation rules to generate business entities with the same business rules on the client. There are some limitations to the attributes that the default code generator can use. We'll also discuss these limitations in this section.

    When WCF RIA Services Triggers Validation

    The class in WCF RIA Services that performs the validation is called the System.ComponentModel.DataAnnotations.Validator class. While it's possible to call this validator class manually, WCF RIA Services will sometimes also call the validator automatically. For example: An entity is automatically validated when it's loaded from the database (to ensure it's valid) and also before you submit any changes to the server.

    When the DataAnnotation's Validator class is called (either explicitly in your code, or implicitly by WCR RIA Services), it will validate all the DataAnnotations validation attributes, including the Validation Application Block attributes, as the latter are also derived from System.ComponentModel.DataAnnotations.ValidationAttribute.

    There are some limitations with regards to using the Validation Application Block attributes, however. Since the DataAnnotations Validation class does not allow you to specify a rule set when validating, any Validation Application Block attribute with a rule set specified will be ignored by the DataAnnotationsValidator class. Also, the DataAnnotationsValidator class will not look for validation rules defined in configuration, so those validation rules will also be ignored.

    If you wish to call validation rules with a specific rule set or call validation rules that are specified in configuration, then you should trigger validation explicitly using the Validation Application Block's Validation class.

    For more information on WCF RIA Services validation, please refer to the WCF RIA Services online documentation on MSDN.

    When the Validation Application Block Triggers Validation

    The Validation Application Block also provides a class that can trigger validation, called Microsoft.Practices.EnterpriseLibrary.Validation.Validator.

    Unlike the Validator class from DataAnnotations, this class is not called automatically by WCF RIA Services. You must explicitly call one of the Validate methods on the validator to initiate validation.

    When you call one of the validate methods on this Validator class, it will call all validation attributes that are defined on your class, including those defined by DataAnnotations attributes. It will also read validation rules defined in configuration and execute those. The Validator class also allows you to specify a rule set to validate. If you do so, then only validation rules that have that specific rule set defined are called.

    The Validation Application Block Validator will also respect the MetadataTypeAttribute in Silverlight. This means that you can use the MetadataTypeAttribute to add Silverlight specific validation rules that will only be used by the Validation Application Block Validator and will be ignored by the WCF RIA Services Validator.

    For more information, please refer to Validating an Object in the Enterprise Library documentation.

    Limitations of the WCF RIA Services Default Code Generator

    The default code generator that ships with WCF RIA Services has a couple of limitations:

    • Incorrect constructor parameters cause attributes to be skipped. The attributes for the Validation Application Block perform validation of their constructor parameters. For example, if you create an EnumConversionValidatorAttribute and you pass null as the enum type, it will throw an argument null exception. The WCF RIA Services code generator will skip any attribute that throws an exception while creating it. This causes a different behavior in Silverlight. On the web server, you will get an exception when you create a business entity with an incorrect validation attribute on it. In the Silverlight client, you will not get an exception because the failing attribute has not been generated.

    • DomainValidatorAttribute. The domain validator attribute allows you to check the value of a property against an array of predefined values. The code generator does not correctly generate attributes with arrays as parameters. To help with that problem, 10 additional constructor parameters have been added. This allows you to specify up to 10 values to validate against.

    • RangeValidatorAttribute does not work properly with decimals and long values. When the WCF RIA Services code generator generates a Range Validator on the client, it will convert all numeric upperbound and lowerbound values to integers. That means that you can only use the range validator on integers.

    • RegexValidatorAttribute and ValidatorCompositionAttribute. By default, the WCF RIA Services code generator will not generate full type names for all parameters. This causes issues for the RegexValidator, because it uses the RegexOptions enum from the System.Text.RegularExpressions namespace and will cause a compile error in the generated code. This also causes issues for the ValidatorCompositionAttribute, because it uses the CompositionType enum, which resides in a different namespace than the attribute. To solve this problem, you must instruct the code generator to include the full type names in the code generation. You can do this by adding the following XML snippet to your Silverlight project file:

      <PropertyGroup>
          <RiaClientUseFullTypeNames>true</RiaClientUseFullTypeNames>
      </PropertyGroup>
      

    Object Validator Attribute and Object Collection Validator Attribute

    You cannot use the ObjectValidatorAttribute or the ObjectCollectionValidatorattribute on a WCF RIA Services business entity directly, without specifying a rule set. These attributes will throw an exception with the message "A validation attribute of type ObjectValidatorAttribute cannot be used to validate values."

    The reason that this exception is thrown is that the Object Validator Attribute and Object Collection Validator Attribute only make sense on the client and wouldn't work as expected on the server.

    Hh852711.note(en-us,PandP.51).gifSharon Says:
    Sharon In the Orders Module for the stock trader, we have two WCF RIA Services business entities: Order and Order Details. On the client, you might want to use the object collection validator so that when you validate the order, its order details get automatically validated as well. The problem is that you might expect the same behavior to occur on the server and that doesn't happen. When you submit an order with order details to the server, you can validate the Order Details objects and the Order object individually, but not as the graph of objects.

    If you accept that the Object Collection Validator Attribute and Object Collection Validator only work on the Silverlight client, then you can add them on the client using the MetadataTypeAttribute. The following code snippet, from the Stock Trader Order Module demonstrates how to do this:

    [MetadataType(typeof(Order.OrderMetadata))]
    public partial class Order
    {
        internal class OrderMetadata
        {
            // When validating the Order, also validate the OrderDetails
            [ObjectCollectionValidator]
    
            // when validating with the ruleset "WarningRuleset", 
            // validate the orderdetails also with ruleset "WarningRuleset" .
            [ObjectCollectionValidator(typeof(OrderDetails), "WarningRuleset", 
                  Ruleset = "WarningRuleset")] 
    
            public EntityCollection<OrderDetails> OrderDetails { get; set; }
        }
    }
    

    In the Silverlight client, the Order class has been generated by WCF RIA Services, with all the validation attributes that where specified in metadata on the server. By using a partial class, you can specify a Silverlight-specific OrderMetadata class, which contains additional validation rules that will only be used by the Validation Application Block in Silverlight.

    Performing Server-Side Validation with Rule Sets Or Validation Rules Defined in Configuration

    When you submit a WCF RIA Services business entity to the server, it will automatically be validated by WCF RIA Services using the DataAnnotations Validator class. However, DataAnnotations doesn't support rule sets or validation rules that are defined in configuration, so these validation rules will not be executed automatically.

    If you wish to execute validation rules that use rule sets or are defined in configuration, you will need to explicitly use the Validation Application Block Validator. If a validation error occurs, then you will need to throw a ValidationException, from the System.ComponentModel.DataAnnotations namespace. In Silverlight, this will be picked up by WCF RIA Services and it will set the Validation Result on the correct object instance.

    The Stock Trader contains a helper class to help with this server-side validation:

    public class EnterpriseLibraryServerValidator
    {
        public void Validate(object objectToValidate)
        {
            Validate(objectToValidate, string.Empty);
        }
        public void Validate(object objectToValidate, string ruleset)
        {
            IEnumerable<ValidationResult> validationResults = 
                 GetValidationResults(objectToValidate, ruleset);             
    
            if (validationResults.Any())
            {
                throw new ValidationException(validationResults.First(), null, 
                    objectToValidate);
            }
        }
    
        public IEnumerable<ValidationResult> GetValidationResults(
             object objectToValidate)
        {
            return GetValidationResults(objectToValidate, string.Empty);
        }
        public IEnumerable<ValidationResult> GetValidationResults(
            object objectToValidate, string ruleset)
        {
            var validator = ValidationFactory.CreateValidator(
                objectToValidate.GetType(), ruleset);
    
            var entlibValidationResults = validator.Validate(objectToValidate);
    
            return TranslateToDataNotationsValidationResult(entlibValidationResults);
        }
    
        IEnumerable<ValidationResult> TranslateToDataNotationsValidationResult(
            ValidationResults entlibValidationResults)
        {
            foreach(var result in entlibValidationResults)
            {
                yield return new ValidationResult(result.Message, new []{result.Key});
            }
        }
    }
    

    This class, called the EnterpriseLibraryServerValidator will help you to trigger the Validation Application Block validation, translate any validation results to a list of Data Annotations Validation Results and then throw the correct type of exception. It will also allow you to pass a rule set to execute conditional validation rules.

    Using the Validation Application Block in a WCF Data Services Application

    WCF Data Services is a component of the .NET Framework that enables you to create services that use the Open Data Protocol (OData) to expose and consume data over the Web or intranet by using the semantics of representational state transfer (REST). OData exposes data as resources that are addressable by URIs. Data is accessed and changed by using standard HTTP verbs of GET, PUT, POST, and DELETE. OData uses the entity-relationship conventions of the Entity Data Model to expose resources as sets of entities that are related by associations.

    In Silverlight, you can also consume OData services. The Silverlight WCF Data Services components can generate a proxy for you that will contain a client-side representation of the business entities exposed by the OData Service.

    WCF Data Services doesn't have built in support for validation, like WCF RIA Services, but you can use Enterprise Library to implement validation both on the Silverlight client and / or the server.

    Using the Metadata Type to Define Validation Rules

    Both on the server and on the Silverlight client, by default, WCF Data Services will generate your business entities for you. That means that you cannot add validation attributes to your business entities directly, but must add them to metadata classes that you have defined using the MetadataType attribute.

    The following code sample, from the Account Holder module in Stock Trader V2, demonstrates how you can add validation rules to the AccountHolder class in meta data:

    [MetadataType(typeof(AccountHolderMetadata))]
    public partial class AccountHolder
    {
        [HasSelfValidation]
        private class AccountHolderMetadata
        {
            [StringLengthValidator(1, RangeBoundaryType.Inclusive, 0, 
    RangeBoundaryType.Ignore, MessageTemplate = "The first name is required")]
            public string FirstName { get; set; }
        }
    }
    
    Hh852711.note(en-us,PandP.51).gifEd Says:
    Ed In the Stock Trader V2, we're using linked files to share these validation rules between the Silverlight client and the server. We did need to make a couple of tweaks to get that to work. We had to make sure the namespace used for the AccountHolder class is the same in both the client and server. Also, the MetadataType attribute in Silverlight is located in a different namespace, as it is provided by the Validation Application Block and not by the built-in DataAnnotations namespace. We added conditional compilation instructions to solve this problem, so the correct namespaces are used.

    Performing Server-side Validation

    When you wish to perform validation on the server and propagate these validation results to the client so you can display them in the user interface, then there are three steps you'll need to perform:

    • On the server, add Change Interceptors to trigger validation. The way that WCF Data Services allow you to implement custom validation is through methods that are decorated with the ChangeInterceptor attribute.To get avalidation error to propagate from the server to the client, you will need to encapsulate it in a DataServiceException instance. Stock Trader V2 shows how you can do this using a helper called the DataServicesValidationHelper. The following example, from the AccountHolderService shows how this is implemented in the Stock Trader:

      [ChangeInterceptor("BankAccountSet")]
      public void OnChangeBankAccount(BankAccount account, UpdateOperations operations)
      {
          /// ...
      
          DataServicesValidationHelper.Validate(account, operations);
      
          if (account.Number == "123456")
          {
              var results = new ValidationResults();
              results.AddResult(new ValidationResult("Our records indicate that you are not the owner of bankaccount with number '123456' (Server side validation rule)", account, "Number", null, null));
              DataServicesValidationHelper.ThrowDataServiceException(results);
          }
      }
      
    • On the client, parse the exception to retrieve the Validation Results. When an exception occurs on the server, WCF Data Services will serialize the exception to XML. When the exception reaches the client, you will need to parse the XML to retrieve the exception that occurred on the server. The Stock Trader V2 application also contains a DataServicesValidationHelper Silverlight class to help with this parsing. The following example shows how you can get use the DataServicesValidationHelper to extract validation results from a data services exception.

      ValidationResults validationResults;
      if (DataServicesValidationHelper.TryGetValidationResults(dataServicesException, out validationResults))
      {
          return new ValidationErrorException(validationResults);
      }
      else
      {
          return dataServicesException;
      }
      

    Next Topic | Previous Topic | Home

    Last built: July 8, 2011