2009-04-06 14 views
16

me Haver un simple lista de botones de radio en mi página que me hacen con la siguiente en mi opinión:ASP.NET MVC Html.RadioButton Excepción

<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, ninguno de los botones está seleccionado. La validación está allí para obligarlos a elegir y no aceptar un valor predeterminado. Por lo tanto, estos dos botones de radio se unen a una anulable propiedad int en mi modelo declarada como:

public int? gender { get; set; } 

Así que si no seleccionan un botón, y se someten a la página, la propiedad de género será nula que indica que se no seleccionó La siguiente validación es llamado por el controlador durante el mensaje:

if (!gender.HasValue) 
    ModelState.AddModelError("gender", "gender required"); 

Pero, si falla la validación (que no eligieron), a continuación, durante la fase de representación, la siguiente excepción es lanzada por el marco MVC:

System.NullReferenceException was unhandled by user code 
    Message="Object reference not set to an instance of an object." 

En la búsqueda de 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?

EDIT: 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 
+0

¿Puede mostrar el seguimiento de la pila? o la línea donde ocurre el error? – tvanfosson

Respuesta

11

Acabo de intentar algo que hace este trabajo. El problema no ocurre si no realizo 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 del modelo que se está validando. acabo de cambiar ese nombre para ser "sexo2" de la siguiente manera:

<label for="gender">Gender</label> 
<%= Html.RadioButton("gender", 1) %> Male 
<%= Html.RadioButton("gender", 2) %> Female 
<%= Html.ValidationMessage("gender2") %> 

Y he cambiado el código de validación para referirse a este nuevo nombre (a pesar de que la propiedad no existe, aún funciona):

if (!gender.HasValue) 
    ModelState.AddModelError("gender2", "gender required"); 

Esto funciona como desee.

Hubiera pensado que el otro debería haber funcionado, pero esta es una solución simple y lo estoy documentando aquí.

EDIT: Por cierto, traté de cambiar la propiedad de género a una cadena en lugar de una int nullable, y ocurre el mismo problema exacto.

La solución parece ser el uso de un nombre de clave diferente para el mensaje de validación.

1

Es posible que desee intentar cambiar el sexo a una cadena (M/F) en lugar de un int y ver si eso funciona.

Si absolutamente debe tenerlo como un int, siempre puede traducir en el 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 en su comentario, es posible que desee añadir:

<%= Html.RadioButton("displayGender", 
        string.Empty, 
        true, // this is the default 
        new { @style = "display: none;" }) %> 

Esto asegurará que displayGender que se envía de vuelta (siempre habrá una radio elegido) y creo que el valor será de cadena . Vacío en lugar de una referencia nula. Si esto funciona, es posible que desee intentar volver al int nullable.

+0

Lo mismo sucede con una cadena en el mismo lugar. Incluso la cadena es nula cuando no se realiza ninguna elección. Y el error no ocurre si no hago la validación. – davcar

+0

Trate de mantenerlo como una cadena y agregue una radio "oculta" que tenga una cadena de valores vacía. Actualizaré mi ejemplo. Creo que no espera que un botón de opción tenga un valor nulo, por lo que no se verifica antes de intentar convertirlo. – tvanfosson

+0

Ah, ya veo, es interesante tener un botón de opción predeterminado oculto. Gracias por la idea. – davcar

1

Trate de añadir la siguiente línea de código después de la ModelState.AddModelError():

ModelState.SetModelValue("gender", ValueProvider["gender"]); 
7

Esto es muy similar, si no igual a la cuestión casilla: El método Html.Checkbox() ayudante genera un campo oculto con una falsa valor. Si este campo falta, el navegador no enviaría ningún dato para las casillas no marcadas.

Un radiobutton, sin embargo, se supone que 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 creo que es la razón por la que no lo es.

La solución para mí fue añadir un campo oculto de la siguiente manera:

<%= Html.RadioButton("gender", 1) %> Male 
<%= Html.RadioButton("gender", 2) %> Female 
<%= Html.Hidden("gender", null) %> 
1

Si desea alambre en la validación del lado del cliente. Omita el helper html y escriba a mano sus radios, dándoles atributos para data-val y data-val-required. 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."/> 
Cuestiones relacionadas