RSS

ASP.NET MVC Html.RadioButton Generates Invalid XHTML

27 Feb

It was pointed out to me by a colleague that the Html.RadioButton(…) extension methods produce invalid XHTML. The output is invalid because, by default, the method will duplicate html “id” attributes. For example, let’s say I have a Colours View Model…

public enum Colours
{
    Red,
    Blue,
    Green
}

public class ColoursViewModel
{
  public Colours ChosenColour
  {
    get;
    set;
  }
}

Then I could create a simple action like this …

public class TestController
{
    public ActionResult SelectColour()
    {
        return View(new ColoursViewModel());
    }
}

… that rendered the following view …

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ColoursViewModel>" %>
<%= Html.RadioButton("ChosenColour", "Red"); %>
<%= Html.RadioButton("ChosenColour", "Green"); %>
<%= Html.RadioButton("ChosenColour", "Blue"); %>

The MVC framework will automatically bind my view model’s “ChosenColour” property to the radio button collection so that I can post the results back like this…

public class TestController
{
    [AcceptVerbs(HttpVerbs.Post)]
    public string SelectColour(ColoursViewModel viewModel)
    {
        return "You chose " + viewModel.ChosenColour.ToString();
    }
}

The problem here is that the generated html looks like this (notice the duplicate id attributes)…

This means that we cannot use the “for” attribute on any labels associated with the individual radio buttons nor can we use javascript to select the radio button when that associated label is clicked.

This is how you fix the problem…

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ColoursViewModel>" %>
<%= Html.RadioButton("ChosenColour", "Red", new { id = "chooseRed" }); %>
<%= Html.RadioButton("ChosenColour", "Green", new { id = "chooseGreen" }); %>
<%= Html.RadioButton("ChosenColour", "Blue", new { id = "chooseBlue" }); %>

… which will generate this html fragment…

<input id="chooseRed" name="ChosenColour" type="radio" value="Red">
<input id="chooseGreen" name="ChosenColour" type="radio" value="Green">
<input id="chooseBlue" name="ChosenColour" type="radio" value="Blue">

The point I’m trying to make here is that the id attribute should be a first class parameter of the RadioButton extension method. I shouldn’t have to override it using the htmlAttributes parameter. This is what the official extension methods look like…

public static string RadioButton(this HtmlHelper htmlHelper, string name, object value);
public static string RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes);
public static string RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes);
public static string RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked);
public static string RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes);
public static string RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes);

You could consider making a change to the MVC framework libraries to include the id, thus decoupling it from the name. For example..

public static string RadioButton(this HtmlHelper htmlHelper, string name, string id, object value);

So anyway, the take-away from this blog post is “Html.RadioButton(…) will produce invalid XHTML unless you pay attention.”

Advertisements
 
2 Comments

Posted by on February 27, 2010 in ASP.Net MVC

 

2 responses to “ASP.NET MVC Html.RadioButton Generates Invalid XHTML

  1. Jennifer

    April 28, 2010 at 3:47 pm

    Thank you for this.The syntax for VB is:<%= Html.RadioButton("ChosenColour", "Blue", New With {.id = "choosered"}); %>

     
  2. Chris Arnold

    April 28, 2010 at 6:51 pm

    My pleasure. Thanks for the comment.

     

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: