ASP.NET MVC Html.RadioButton Exception
asp.net-mvc (5)
Acabo de probar algo que hace que esto funcione. El problema no se produce si no hago el paso de validación pero, por supuesto, necesito la validación. Eso me dio una pista para la solución.
El método ValidationMessage HtmlHelper toma un argumento de cadena que es el nombre de la propiedad o el objeto modelo que se está validando. Acabo de cambiar ese nombre para que sea "gender2" de la siguiente manera:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender2") %>
Y cambié el código de validación para referirme a este nuevo nombre (aunque esa propiedad no existe, sigue funcionando):
if (!gender.HasValue)
ModelState.AddModelError("gender2", "gender required");
Esto funciona como se desee.
Pensé que el otro debería haber funcionado, pero esta es una solución simple y lo estoy documentando aquí.
EDITAR: Por cierto, traté de cambiar la propiedad de género a una cadena en lugar de un int. Que puede contener nulos, y ocurre el mismo problema.
La solución alternativa todavía parece estar utilizando un nombre de clave diferente para el mensaje de validación.
Tengo una lista de botones de radio simple en mi página que represento con lo siguiente en mi vista:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender") %>
Tenga en cuenta que cuando el usuario ve inicialmente esta entrada, no se selecciona ningún botón. La validación está ahí para obligarlos a elegir y no aceptar un valor predeterminado. Por lo tanto, estos dos botones de opción están vinculados a una propiedad int anulable en mi modelo declarada como:
public int? gender { get; set; }
Por lo tanto, si no seleccionan un botón y envían la página, la propiedad de género será nula, lo que indica que no seleccionaron. La siguiente validación es llamada por el controlador durante la publicación:
if (!gender.HasValue)
ModelState.AddModelError("gender", "gender required");
Pero, si la validación falla (no eligieron), durante la fase de representación, el marco MVC lanza la siguiente excepción:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Al buscar una solución a este problema, noté que varios tenían este problema. Estoy usando ASP.NET MVC 1.0. Encontré el lugar en el código donde se produce este error utilizando .NET Reflector.
La pregunta es ¿cómo hacer que esto funcione correctamente?
EDITAR: para añadir 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
Es posible que desee intentar cambiar el género a una cadena (M / F) en lugar de un int y ver si eso funciona.
Si es absolutamente necesario tenerlo como un int, siempre se podría traducir en la parte de atrás.
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 en su comentario, es posible que desee agregar:
<%= Html.RadioButton("displayGender",
string.Empty,
true, // this is the default
new { @style = "display: none;" } ) %>
Esto asegurará que displayGender se vuelva a publicar (siempre habrá una radio elegida) y creo que el valor será string.Empty en lugar de una referencia nula. Si esto funciona, puede intentar cambiar de nuevo a int int.
Esto es muy similar, si no es igual al problema de la casilla de verificación: el método auxiliar Html.Checkbox () genera un campo oculto con un valor falso. Si faltara este campo, el navegador no enviaría ningún dato a las casillas sin marcar.
Sin embargo, se supone que un botón de radio tiene un valor, y los valores posibles pueden ser más de uno. En este caso, no es tan fácil manejar el caso de no selección, que supongo que es la razón por la que no lo es.
La solución para mí fue agregar un campo oculto de la siguiente manera:
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.Hidden("gender", null) %>
Intente agregar la siguiente línea de código después de ModelState.AddModelError()
:
ModelState.SetModelValue("gender", ValueProvider["gender"]);
Si desea cablear en la validación del lado del cliente. Omita el ayudante html y escriba a mano sus radios, dándoles atributos para el valor de datos y el valor de datos requerido. Me gusta esto.
<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."/>