Notes on Templates and Data Annotations in MVC 2

Sunday, July 25, 2010

Brad Wilson has an excellent series of 5 blog posts on model metadata and templates you can use to get started with templates and metadata in ASP.NET MVC 2. Here are a couple notes I've made around some of aspects that commonly confuse developers (including me, it seems).

1. Although most of the metadata attributes live in the System.ComponentModel.DataAnnotations namespace, there are a few exceptions. If you aren't seeing something you need in Intellisense, then try adding System.ComponentModel (for the popular DisplayName attribute) and System.Web.Mvc (for the popular HiddenInput attribute).

2. Some of the confusion around data annotations exists because the MVC runtime doesn't recognize every data annotation attribute built into .NET. For example, using [Editable(false)] is tempting, but you'll find it doesn't have any impact in model binding, validation, or templating. The built-in templates respect 7 data annotation attributes:

  • DisplayColumn
  • HiddenInput
  • UIHint
  • DataType
  • DisplayFormat
  • ScaffoldColumn
  • DisplayName

3. There are two additional attributes the default model metadata provider will consume:

  • ReadOnly
  • Required

However, the built-in templates do not make use of the information from these attributes. For example, you can apply [ReadOnly(true)] to a property, but you'll find the default templates in use by helpers like Html.EditorForModel will still show a textbox input for the user to enter a value. If you want to get rid of the input with EditorForModel you'll need a custom template, or you'll need to use [ScaffoldColumn(false)].

Note the default model binder does respect the ReadOnly attribute, so it won't move a value into a property with [ReadOnly[false)]. Also, the built-in validation logic respects the Required attribute. These attributes definitely have value in an MVC app, but they won't influence the UI rendered by the default templates.


Comments
gravatar Wes Monday, July 26, 2010
I think all this translates to: don't use MVC2 templates. HtmlTags have proven to be far more flexible and productive.
gravatar Tom Styles Thursday, July 29, 2010
If you follow Brad's example then the object.ascx template can be easily modified to pay attention to the readonly field.

Insert at appropriate point

<% if (prop.IsReadOnly) { %>
<%= Html.Display(prop.PropertyName) %>
<% } else { %>
<%= Html.Editor(prop.PropertyName) %>
<% } %>
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!