I haver a simple radio button list on my page that I render with the following in my view:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender") %>
Note that when the user initially sees this input, neither button is selected. The validation is there to force them to choose and not accept a default. Therefore, these two radio buttons are bound to a nullable int property in my model declared as:
public int? gender { get; set; }
So if they do not select a button, and submit the page, the gender property will be null indicating that they did not select. The following validation is called by the controller during the post:
if (!gender.HasValue)
ModelState.AddModelError("gender", "gender required");
But, if the validation fails (they did not choose), then during the rendering phase, the following exception is thrown by the MVC framework:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
In searching for for a solution to this problem, I noted several had this problem. I am using ASP.NET MVC 1.0. I found the place in the code where this error is thrown using .NET Reflector.
The question is how to make this work correctly?
EDIT: to add stacktrace:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="System.Web.Mvc"
StackTrace:
at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType)
at System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value)
at ASP.views_vbs_register_aspx.__RenderregisterContent(HtmlTextWriter __w, Control parameterContainer) in c:\Users\David\Documents\BellevueProject\Bellevue\BellevueTeachers\Forms\Views\VBS\Register.aspx:line 42
RadioButton is a kind of toggle control which receives the input from a user in the form of a click. In radio-button, all buttons are connected with the same group name and id. User can select any one button option from the given radiobuttons or list.
Create Radio buttons in ASP.NET MVC The HtmlHelper class include two extension methods to generate a <input type="radio"> HTML control in a razor view: RadioButtonFor() and RadioButton() . We will use the following Student model class throughout this article.
Note: The radio group must have share the same name (the value of the name attribute) to be treated as a group. Once the radio group is created, selecting any radio button in that group automatically deselects any other selected radio button in the same group.
This is very similar, if not equal to the checkbox issue: The Html.Checkbox() helper method generates a hidden field with a false value. If this field were missing, the browser would not send any data for uncheked boxes.
A radiobutton, however, is supposed to have a value, and the possible values can be more than one. In this case it is not so easy to handle the non-selection case, which I guess is the reason it isn't.
The workaround for me was to add a hidden field as follows:
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.Hidden("gender", null) %>
I just tried something that makes this work. The problem does not occur if I do not do the validation step but of course I need the validation. That gave me a clue for the solution.
The ValidationMessage HtmlHelper method takes a string argument that is the name of the property or model object being validated. I just changed that name to be "gender2" as follows:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender2") %>
And I changed the validation code to refer to this new name (even though that property does not exist, it still works):
if (!gender.HasValue)
ModelState.AddModelError("gender2", "gender required");
This works as desired.
I would have thought the other should have worked, but this is a simple workaround and I am documenting that here.
EDIT: By the way I tried changing the gender property to a string instead of a nullable int, and the same exact problem occurs.
The work around still seems to be in using a different key name for the Validation Message.
You might want to try changing gender to a string (M/F) instead of an int and see if that works.
If you absolutely must have it as an int, you could always translate on the back end.
private int? gender { get; set; }
public string displayGender
{
get
{
return this.gender.HasValue
? (this.gender.Value == 1 ? "M" : "F" )
: null;
}
set
{
this.gender = null;
if (value == "M")
this.gender = 1;
else if (value == "F")
this.gender = 2;
}
}
<label for="gender">Gender</label>
<%= Html.RadioButton("displayGender", "M") %> Male
<%= Html.RadioButton("displayGender", "F") %> Female
<%= Html.ValidationMessage("displayGender") %>
Base on your comment, you may want to add:
<%= Html.RadioButton("displayGender",
string.Empty,
true, // this is the default
new { @style = "display: none;" } ) %>
This will ensure that displayGender gets posted back (there will always be a chosen radio) and I think the value will be string.Empty instead of a null reference. If this works, you may want to try switching back to the nullable int.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With