ASP.NET MVC: Create Custom Attributes for MetaData

Posted by: Malcolm Sheridan , on 4/14/2011, in Category ASP.NET MVC
Views: 137526
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

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan

Page copy protected against web site content infringement 	by Copyscape

Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Andrew Gunn on Thursday, April 14, 2011 10:25 AM
Great idea. Totally overkill but I like it. I don't like the idea of a direct link between POCOs and HTML attributes. You could define your models as partial classes (in a separate assembly maybe), and then apply the metadata similar to the way done by Scott Gu for validation (
Comment posted by Malcolm Sheridan on Thursday, April 14, 2011 6:37 PM

Thanks.  I tend to agree that it is overkill.  The one benefit is all of your code is separated from the front end, so your views are kept "clean".  But on the other hand, what are views for if they're not to contain the HTML.  Anyway this article just shows how this is possible.

Thanks for the feedback.
Comment posted by Fred Coder on Friday, April 22, 2011 12:42 AM
Looks like the same over-engineering approach that has cost so much time and money in Java multi-tiered development.  
Comment posted by Skywalker on Tuesday, May 24, 2011 6:05 AM
Even though I wouldn;t encourage a direct link between POCOs and HTML attributes, this post does show how one can create custom attributes, attach them to a POCO and how to use that attribute from the view. And that is EXACTLY what I was looking for! (In y case, I need a HelpTextAttribute which I want to attach to certain properties of my viewmodels and use that inside a generic Object TemplateEditor). So a BIG thank you for this excellent post!
Comment posted by Skywalker on Tuesday, May 24, 2011 6:09 AM
By the way, I just figured that in my case I could simply use the AdditionalMetadataAttribute to decorate my properties which require helptext
Comment posted by Skywalker on Tuesday, May 24, 2011 6:57 AM
Even better: there is an existing DisplayAttribute which takes a Description parameter (among several other userful ones!). See: for more details.
Comment posted by @echarbeneau on Friday, June 10, 2011 8:10 AM
I don't think this is over kill. Consider this; you could use this on your ViewModels, and as long as it's part of convention for that codebase (ie. your not mixing and matching convention all over your view) I wouldn't have a problem using this as is. Besides this specific scenario, I think it's a great example of how custom attributes work, and I'm sure I'll be using it for something.
Comment posted by Guillermo on Monday, February 4, 2013 2:03 PM
I think it's not far more overkill than the way the framework currently does it. It will use it's own ModelMetaDataProvider anyway, even if you don't specify additional attributes. Still, the way the framework does it seems sort of overkill to me.