7

I want to use the strongly-typed HTML helpers in ASP.NET MVC 2 with a property of my model which is Nullable<T>.

Model

public class TicketFilter {
    public bool? IsOpen { get; set; }
    public TicketType? Type{ get; set; } // TicketType is an enum
    // ... etc ...
}

View (HTML)

<p>Ticket status:
  <%: Html.RadioButtonFor(m => m.IsOpen, null) %> All
  <%: Html.RadioButtonFor(m => m.IsOpen, true) %> Open
  <%: Html.RadioButtonFor(m => m.IsOpen, false) %> Closed
</p>
<p>Ticket type:
  <%: Html.RadioButtonFor(m => m.Type, null) %> Any
  <%: Html.RadioButtonFor(m => m.Type, TicketType.Question) %> Question
  <%: Html.RadioButtonFor(m => m.Type, TicketType.Complaint) %> Complaint
  <!-- etc -->
</p>

However, using the helpers in this way throws an ArgumentNullException -- the second parameter cannot be null. Instead of null, I've tried using new bool?()/new TicketType? as well as String.empty. All result in the same exception. How can I work around this and bind a control to a null value?

Brant Bobby
  • 14,956
  • 14
  • 78
  • 115
  • What would you expect a null value for a radio button to return ? – Clicktricity Oct 26 '10 at 20:56
  • I'd imagine a blank string, or even the word "null". Presumably `DefaultModelBinder` would know what to do when building a `TicketFilter` from the form values to pass to my action method, no? – Brant Bobby Oct 26 '10 at 21:08

3 Answers3

8

Try this:

<p>Ticket status:
  <%: Html.RadioButtonFor(m => m.IsOpen, "") %> All
  <%: Html.RadioButtonFor(m => m.IsOpen, "true") %> Open
  <%: Html.RadioButtonFor(m => m.IsOpen, "false") %> Closed
</p>
<p>Ticket type:
  <%: Html.RadioButtonFor(m => m.Type, "") %> Any
  <%: Html.RadioButtonFor(m => m.Type, "Question") %> Question
  <%: Html.RadioButtonFor(m => m.Type, "Complaint") %> Complaint
  <!-- etc -->
</p>
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Huh, well that's weird. I *swear* I tried `""` and `string.Empty` before and it threw an exception, but now it works! However: When the property of the model is null, none of the radio buttons are checked (since `"" != null`, I guess). I can get around this with a bit of JS, but is there a server-side solution? – Brant Bobby Oct 28 '10 at 15:32
  • 3
    Unfortunately this cannot be done at the server side. The problem here is that you are using null to represent a real state which is All. So you are using a nullable boolean type to represent four possible states: open, closed, all and none. So instead of using a nullable boolean you could use a nullable enum with 3 values: Open, Closed and All and if the property is null, none of the three radio buttons will be selected. Same stands true for the Type property: you could use Any, Question and Compliant values so that you never have to use null or string.Empty as value in the helper. – Darin Dimitrov Oct 28 '10 at 15:42
4

Darin's answer is correct, but doesn't select the correct radio button when the property is null. The following code will fix that...

<%: Html.RadioButtonFor(m => m.Type, "", new { @checked = (Model.Type == null) }) %> Any
<%: Html.RadioButtonFor(m => m.Type, "Question") %> Question
<%: Html.RadioButtonFor(m => m.Type, "Complaint") %> Complaint
wycleffsean
  • 1,377
  • 1
  • 11
  • 16
0

I believe you should be using the RadioButtonListFor HTML helper. Take a look at this SO post.

Community
  • 1
  • 1
Dustin Laine
  • 37,935
  • 10
  • 86
  • 125