ASP.NET MVC Html.RadioButtonList Blues

Recently I upgraded our ASP.NET MVC project from Preview 5 to RC2. At first I thought the Html.RadioButtonList extension was removed completely, but then realized that it was no longer in the main MVC assembly, but was moved to the Futures project (although I don't know why).

The Preview 5 version of the Html.RadioButtonList rendered the following output...

However, once I got my code to compile I went to run my application only to find that it rendered two RadioButtons with no labels! Where did the labels go?

I pulled down the source code for the 1.0 release (just to make sure it wasn't fixed in the RTM as opposed to the RC2) and dove into the extension code. Nowhere did I see the labels being applied in the extension.


//C:\...\MVC-RTM\MVC\src\MvcFutures\Mvc\RadioExtensions.cs
private static string[] RadioButtonListInternal(this HtmlHelper htmlHelper, string name, IEnumerable selectList, bool usedViewData, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(name)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
if (selectList == null) {
throw new ArgumentNullException("selectList");
}

// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (!usedViewData) {
object defaultValue = htmlHelper.ViewData.Eval(name);

if (defaultValue != null) {
IEnumerable defaultValues = new[] { defaultValue };
IEnumerable values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
HashSet selectedValues = new HashSet(values, StringComparer.OrdinalIgnoreCase);
List newSelectList = new List();

foreach (SelectListItem item in selectList) {
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
}

selectList = newSelectList;
}
}

IEnumerable radioButtons = selectList.Select<SelectListItem, string>(item => htmlHelper.RadioButton(name, item.Value, item.Selected, htmlAttributes));

return radioButtons.ToArray();
}
</pre>

Next I looked at the Unit Tests for the extesion. I was please to see tests for the RadioButtonList, but was shocked to see that the asserts were verifying html that didn't have any labels applied!


//C:\...\MVC-RTM\MVC\test\MvcFuturesTest\Mvc\Test\RadioExtensionsTest.cs
[TestMethod]
public void RadioButtonListItemSelected() {
// Arrange
HtmlHelper htmlHelper = TestHelper.GetHtmlHelper(new ViewDataDictionary());

// Act
string[] html = htmlHelper.RadioButtonList("FooList", GetRadioButtonListData(true));

// Assert
Assert.AreEqual(@"<input id=""FooList"" name=""FooList"" type=""radio"" value=""foo"" />", html[0]);
Assert.AreEqual(@"<input id=""FooList"" name=""FooList"" type=""radio"" value=""bar"" />", html[1]);
Assert.AreEqual(@"<input checked=""checked"" id=""FooList"" name=""FooList"" type=""radio"" value=""baz"" />", html[2]);
}

private static SelectList GetRadioButtonListData(bool selectBaz) {
List list = new List();
list.Add(new RadioItem { Text = "text-foo", Value = "foo" });
list.Add(new RadioItem { Text = "text-bar", Value = "bar" });
list.Add(new RadioItem { Text = "text-baz", Value = "baz" });
return new SelectList(list, "value", "TEXT", selectBaz ? "baz" : "something-else");
}

private class RadioItem {
public string Text {
get;
set;
}

public string Value {
get;
set;
}
}
</pre>

Where does that leave us? I guess using the Futures Html.RadioButtonList isn't all that helpful after all. So, instead I decided to loop through my DataSource and create individual Html.RadioButton and Label combinations.



<%
var radioButtonList = new SelectList(new List {
new ListItem { Text = "Current", Value="false", Selected=true },
new ListItem { Text = "Other", Value="true"}}, "Value", "Text", "false");
var htmlAttributes = new Dictionary<string, object> {
{ "class", "radioButtonList" },
{ "onclick", "if(eval(this.value)) { $('#tblDate').show('slow'); } else { $('#tblDate').hide('slow'); }" }
};
foreach (var radiobutton in radioButtonList) { %>
<%=Html.RadioButton("rblDate", radiobutton.Value, radiobutton.Selected, htmlAttributes)%>

<% } %>
</pre>

If you enjoyed this post, please consider sharing it with others via the following Twitter or Reddit buttons. Also, feel free to checkout my egghead.io profile page for addition free and subscription lessons, collections, and courses. As always, you can reach out to me on Twitter at @elijahmanor. Thanks and have a blessed day!

Reddit