I haver a simple radio button list on my page that I render with the following in my view:
<%=
Try adding the following line of code after the ModelState.AddModelError()
:
ModelState.SetModelValue("gender", ValueProvider["gender"]);
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) %>
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 want to wire in client-side validation. Skip the html helper and hand-write your radios, giving them attributes for data-val and data-val-required. Like this.
<input type="radio" name="displayGender" id="displayGender" value="1" data-val="true" data-val-required ="The gender field is required."/>
<input type="radio" name="displayGender" id="displayGender" value="2" data-val="true" data-val-required ="The gender field is required."/>
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.