Understanding Common Validator Properties
There are a number of properties defined for the Validator class. These properties are also exposed by the ValidatorAttribute class, which means that they can be used with any attribute that derives from this class.
These properties are the following:
- MessageTemplate. For more details, see Using the Message Template Property.
- MessageTemplateResourceName and MessageTemplateResourceType . For more details, see Using the Message Template Resources.
- Negate. For more details, see Using the Negate Property.
- Tag. For more details, see Using the Tag Property.
- Ruleset. For more details, see Using the Ruleset Property.
Using the Message Template Property
If a validation operation fails, the application block creates a ValidationResult object. This object contains several properties that can provide more detail about the nature of the failure. The Message property is particularly important. It allows you to provide a human-readable explanation of the validation failure.
Using the Default Message Template
Each Validator type includes one or more default message templates. A validator instance uses this default message template if you do not specify a custom message template. Typically, the default message template provides an accurate but very generic description of the failure, such as "The string does not match the specified Regular Expression pattern." (Validators that support the Negate property generally provide a different default message template depending on whether or not the validator has been negated.)
In some cases, the default message templates may be detailed enough to be meaningful to users, but in many situations, it is helpful to provide your own message templates. For example, instead of using "The string does not match the specified Regular Expression pattern," you can use a more descriptive message such as "The password must contain at least one uppercase letter, one lowercase letter, and one number."
Specifying a Custom Message Template
The validators that are provided with the application block load their default message templates from the resources included in the Microsoft.Practices.EnterpriseLibrary.Validation.dll assembly. If you want to customize the default message templates, you can modify the resource strings in the Resources.resx file and rebuild the assembly. You can also create additional resource files to support multiple cultures. The Validation Application Block uses the current thread’s CurrentUICulture property to determine which culture to use when it loads the resources.
You can specify message templates for validators that are created using configuration, attributes, or code. For validators that you create from configuration or attributes, you can either use hard-coded literal strings or references to strings that are contained in an assembly’s resources.
To specify a hard-coded literal message template for a validator, enter the string into the validator's MessageTemplate property, either as a configuration property on the validator instance or as a named property in the attribute declaration. The following code example specifies the MessageTemplate property in the attribute declaration.
[RegexValidator(@" \d{5}(-\d{4})?", MessageTemplate="The supplied ZIP code is invalid")]
'Usage
<RegexValidator("\d{5}(-\d{4})?", MessageTemplate:="The supplied ZIP code is invalid")>
Using the Message Template Resources
If you do not want to specify a message template with a literal string, an alternative is to use a resource file that contains the message template string. This approach is helpful if you must localize the message content.
The MessageTemplateResourceName and MessageTemplateResourceType properties allow you to do this. The MessageTemplateResourceName property defines the name of the resource for message templates. The MessageTemplateResourceType property defines the name of the type that is used for the message template resource.
To specify a resource-based message template for a validator, enter the resource name into the MessageTemplateResourceName property of the validator and the type containing the resource into the MessageTemplateResourceType property. Both properties should be specified either as a configuration property on the validator instance or as a named property in the attribute declaration.
Note
If two resources within a given assembly have the same resource name, the first one will be used (regardless of the actual resource type). The resource string loader performs a search across all of the resources within an assembly when resolving the named resource. Due to the non-deterministic ordering of resources within an assembly, duplicated resource names may result in unpredictable behavior. Use a unique resource name for each resources entry to avoid any potential issues.
The following code example specifies these properties in the attribute declaration.
[RegexValidator(@"\d{5}(-\d{4})?",
MessageTemplateResourceName="InvalidZipResource",
MessageTemplateResourceType=typeof(MyApplication))]
'Usage
<RegexValidator("\d{5}(-\d{4})?", _
MessageTemplateResourceName:="InvalidZipResource", _
MessageTemplateResourceType:="GetType(MyApplication)")> _
Understanding Message Template Tokens
Custom message templates can contain tokens. The validator replaces these tokens with values before it adds the resulting message to an instance of the ValidationResult class. Tokens are represented by using the strings {0}, {1}, {2}, and so on within the message template strings. All validators provided by the Validation Application Block use the first three tokens {0}, {1}, and {2} for the same purposes. Different validators may also understand additional tokens, beginning with {3}. The following table describes tokens {0}, {1}, and {2}.
Token |
Description |
---|---|
{0} |
This token represents the value of the object that is being validated. Although it can be useful to show the original value as a part of the validation message, you must be careful to avoid injection attacks by escaping any characters that can be used to attack the system that conveys the message to the user. |
{1} |
This token represents the key of the object that is being validated. When the validator is attached to a member of a type such as a property or a field, the key is set to the member name. When the validator is attached to an object, the key is null and the token is replaced by an empty string. |
{2} |
This token represents the tag that is specified on the validator instance. If no tag is supplied, the token is replaced by an empty string. |
For more information about tokens, see String.Format Method on MSDN®.
Using the Negate Property
The Negate property changes the validator's behavior so that it will fail if the condition is met, rather than when it is not met.
Using the Tag Property
The Tag property characterizes the results that are logged by the validator. Typically, you use the Tag property as a way to categorize or filter your results. The following code example uses an attribute to set the Tag property to characterize string length failures.
public class Customer
{
[NotNullValidator(Tag="Missing values")]
[StringLengthValidator(1, 50, Tag="String length problem")]
public CustomerName Name;
}
'Usage
Public Class Customer
<NotNullValidator(Tag:="Missing values")> _
<StringLengthValidator(1, 50, Tag:="String length problem")> _
Public CustomerName As String
End Class
You can filter a collection of validation errors in a ValidationResults instance by using the FindAll method and specifying the value of the Tag property. For more information, see Understanding Validation Results.
Using the Ruleset Property
The Ruleset property names the rule set defined in configuration to which the validator belongs. In the following code example, the DateTimeRangeValidator attributes use different rule sets to allow a longer membership period to gold customers than to standard customers.
public class Customer
{
[DateTimeRangeValidator("2007-10-27T00:00:00", "2008-10-27T00:00:00",
Ruleset="StandardCustomer")]
[DateTimeRangeValidator("2007-10-27T00:00:00", "2010-10-27T00:00:00",
Ruleset="GoldCustomer")]
public DateTime MembershipExpirationDate;
}
'Usage
Public Class Customer
<DateTimeRangeValidator("2007-10-27T00:00:00", "2008-10-27T00:00:00", _
Ruleset:="StandardCustomer")> _
<DateTimeRangeValidator("2007-10-27T00:00:00", "2010-10-27T00:00:00", _
Ruleset:="GoldCustomer")> _
Public MembershipExpirationDate As Date
End Class
You can apply one or more rule sets when you call the Validate method if you want to apply more than one set of rules to a validation operation. For more details, see Validating Objects.