ASP.NET MVC: Create Custom Attributes for MetaData
Posted by: Malcolm Sheridan
in Category ASP.NET MVC
Abstract: The following article shows you how to create a custom attribute to output additional HTML when using a metadata class in MVC.
One of the strong features to come in MVC 2 was the ability to create metadata classes that allowed you to specify the metadata that was linked to the model. You could decorate properties with the StringLength, Range and RegularExpression attribute. Sometimes you want to add HTML attributes to your elements, say if you want to set the tab index for an input control. You could do this, but then you’re adding extra mark-up that could be placed elsewhere:
Wouldn’t it be nicer to omit the anonymous object? I think so and this is one way to do it.
The crux of the code lies with a class that derives from DataAnnotationsModelMetadataProvider. This class implements the default model metadata provider. All you need to do is override CreateMetadata and find the AdditionalValues collection. This is where you’ll insert your own custom object. Here’s the code below:
Calling the base class you can find the metadata for the property. One of the properties is AdditonalValues. This value gets a dictionary that contains additional metadata about the model. Basically what’s happening in the code above is when the view is rendered, the framework will look through all the attributes associated to the property. If it finds an attribute called AdditionalHtml (which we haven’t created yet), it will add it the properties AdditionalValues property. Make sense? Let’s add the AdditionalHtml class now:
The class is intended to be used as an attribute, hence why it’s deriving from Attribute. There’s one public method called OptionalAttributes, and all that does is add values to a dictionary and returns that. This dictionary will be used as the input for the AdditionalValues in the previous section. The public properties relate to attributes you can use on HTML input’s, such as readonly, maxlength and css classes.
To use this new attribute, you need to decorate the properties in your metadata class like this:
This class is linked to the model, Employee, by using the MetadataType attribute:
And finally to use this, I’m using a templated helper to output the view. Because the two properties are strings, the templated helper must be called string.cshtml and reside in the EditorTemplates folder
The final step is to let the framework know it should use this as the default ModelMetadataProvider. This is done through the global.asax file:
When the view is rendered, the framework uses the templated helper to display any properties whose data type is string. If it finds one, it grabs the metadata and checks if it’s been decorated with the AdditionalHtml attribute. If it does, it renders that as the additional html attributes. The result is below:
I like adding additional html attributes this way as it keeps the mark-up nice and clean. It is allot of work to output simple attributes, but isn’t that part of the fun of programming?
The entire source code of this article can be downloaded over here