Strongly Typed <label> elements in ASP.NET MVC 2

19 January 2010 - 11:23 PM / by Dominic Pettifer. 0 Comments

Cool C# Snippets - Generate strongly typed <label> elements in a way that is (IMHO) better than the default method built into ASP.NET MVC 2.

Strongly Typed Html Helpers

In ASP.NET MVC version 2.0 they introduced support for strongly typed <input /> controls. Whereas before you'd have to type something along the lines of:

<%= Html.TextBox("EmailAddress", Model.EmailAddress) %>

The problem being that you could mistype "EmailAddress" and the error wouldn't get picked up until runtime, or you might rename the property "EmailAddress" on your ViewModel, and refactoring tools built into Visual Studio wouldn't pick up the "EmailAddress" string used in the TextBox() method. Now in ASP.NET MVC 2 there is support for strongly typed HTML Helper methods, where any errors can be picked up at compile time:

<%= Html.TextBoxFor(m => m.EmailAddress) %>

Read more at Scott Guthrie's blog (http://weblogs.asp.net/scottgu/archive/2010/01/10/asp-net-mvc-2-strongly-typed-html-helpers.aspx).

Html.LabelFor()

In MVC 2 they also added support for strongly typed <label> elements as well (sort of):

<%= Html.LabelFor(m => m.EmailAddress) %>

...which outputs the following...

<label for="EmailAddress">EmailAddress</label>

The benefits of this method being that it will reliably generate the 'for' attribute that points to the <input /> element's ID its paired with, eg.

<label for=”EmailAddress”>EmailAddress</label>
<input type=”text” id=”EmailAddress” name=”EmailAddress” />

However, Html.LabelFor has no overload that allows you to specify the actual <label> element text, it defaults to the property name (EmailAddress) which looks ugly. You can set the label text via DataAnnotations on the ViewModel class itself eg.

public class AccountView
{
    //-- snip (other properties) --//
    
    [Required]
    [DisplayName(“Your e-mail address:”)]
    public string EmailAddress { get; set; }
}

...and you'll get:

<label for="EmailAddress">Your e-mail address:</label>

Not In My ViewModel Please!

The problem is some people, like me, would consider the <label> text to be a View/Presentation concern specified in the .aspx views, and that it shouldn’t go inside your Model classes. You could just type <label for="EmailAddress"> directly, but then you lose the benefit of strong typing the Input's ID. So I wrote an Html Extension method that generates the control Ids based on the ViewModel Property:

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace MvcLibrary.Extensions
{
    public static class HtmlExtensions
    {
        public static MvcHtmlString FieldIdFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            string inputFieldId = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName);
            return MvcHtmlString.Create(inputFieldId);
        }
    }
}

Which you can use in your Views like this:

<label for="<%= Html.FieldIdFor(m => m.EmailAddress) %>">Your e-mail address:</label>
<%= Html.TextBoxFor(m => m.EmailAddress) %>

I suppose one could just write an overload for the LabelFor() method that takes a string parameter for the label text. However, just generating the input ID has other benefits. For one you’re more in control of the markup if you want to add attributes (class, id etc.) to the <label> element. Secondly the Html.FieldIdFor() method can be used elsewhere you need the dynamically generated control ID, such as in calling JavaScript functions that make the ID of input controls.

<script> $.CoolJQueryFunction('<%= Html.FieldIdFor(m => m.EmailAddress) %>'); </script>

0 Comments on "<label> Elements in ASP.NET MVC"

Post a Comment

Leave a Comment

Comment Details
*
* BBCode: [b]bold[/b], [i]italics[/i], [code]code[/code], [li]bullet point[/li], [h]Heading[/h], [url="http://www.example.com"]link[/url], [quote author="John Smith"]quote[/quote]

Random Image

Fat Greedy Hamster

Fat Greedy Hamster (from the blog And So It Begins (part 2) )

Quick Poll

What is your DIP/IOC Container of choice?

Poll Vote
(see results)
View Comments (0) (See previous polls)

Latest Tweets

  • Blogged: IHttpModule Gotchas – The Init() Method Can Get Called Multiple Times http://bit.ly/96xioE #aspnet

    about 6 hours ago from Echofon
  • @shanselman Give me a free copy of Visual Studio 2010 then! :-)

    about 13 hours ago from Echofon
  • RT: @aaronbassett: Guy comes out of the closet - http://bit.ly/aHMg1o - HAHA!! That's hilarious!!

    about 17 hours ago from Echofon
  • This multiple IHttpModule thing has shaken the foundations of my understanding of ASP.NET. I feel a blog post coming.

    about 18 hours ago from Echofon
  • I've written the following code to get a pseudo App_StartUp event in my IHttpModule (without relying on Global.asax) http://bit.ly/a2AiNI

    about 19 hours ago from Echofon

View Dominic Pettifer's Twitter page.