Defining Attributes in Metadata Classes
In some cases, you may want to locate your validation attributes (both Validation block attributes and .NET Data Annotation validation attributes) in a separate file to the one that defines the class that you will validate. This is a common scenario when you are using tools that generate the class files, and would therefore overwrite your validation attributes. To avoid this you can locate your validation attributes in a separate file that forms a partial class along with the main class file. This approach makes use of the MetadataType attribute from the System.ComponentModel.DataAnnotations namespace.
You apply the MetadataType attribute to your main class file, specifying the type of the class that stores the validation attributes you want to apply to your main class members. You must define this as partial class, as shown here. The only change to the content of this class compared to the attributed versions you saw in the previous sections of this chapter is that it contains no validation attributes.
[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
... Existing members defined here, but without attributes or annotations ...
}
'Usage
<MetadataType(GetType(ProductMetadata))> _
Partial Public Class Product
... Existing members defined here, but without attributes or annotations ...
End Class
You then define the metadata type as a normal class, except that you declare simple properties for each of the members to which you want to apply validation attributes. The actual type of these properties is not important, and is ignored by the compiler. The accepted approach is to declare them all as of type Object. As an example, if your Product class contains the ID and Description properties, you can define the metadata class for it as shown here.
public class ProductMetadata
{
[Required(ErrorMessage = "ID is required.")]
[RegularExpression("[A-Z]{2}[0-9]{4}",
ErrorMessage = "Product ID must be 2 capital letters and 4 numbers.")]
public object ID;
[StringLength(100, ErrorMessage = "Description must be less than 100 chars.")]
public object Description;
}
'Usage
Public Class ProductMetadata
<Required(ErrorMessage:="ID is required.")> _
<RegularExpression("[A-Z]{2}[0-9]{4}", _
ErrorMessage:="Product ID must be 2 capital letters and 4 numbers.")> _
Public ID As Object
<StringLength(100, ErrorMessage:="Description must be less than 100 chars.")> _
Public Description As Object
End Class
For more information, see MetadataTypeAttribute Class on MSDN.