DropDownList que establece el elemento seleccionado en asp.net MVC

Noté lo que me parece un error en asp.net MVC o simplemente estoy haciendo algo mal. Actualmente estoy usando 1.0, así que tal vez esto sea algo que se abordará en la versión 2.0. Pero de cualquier manera, aquí vamos.

Cuando mi modelo de vista tiene una propiedad que es el mismo nombre que el ID declarado para una lista desplegable, el elemento seleccionado se ignora y el html representado no tiene nada seleccionado. No estoy seguro de haber hecho algo mal, pero cambiar el nombre del id soluciona el problema. Simplifiqué el ejemplo, espero que esté claro, de lo contrario, háganmelo saber.

Aquí está mi vista donde el ID declarado es el mismo nombre que mi lista en el modelo:

Y el Html renderizado

 
No Yes

Ahora hagamos un pequeño cambio. Cambiaré la identificación declarada para ser algo diferente.

Aquí está mi vista:

 

Y ahora el html renderizado:

 
No Yes

Tenga en cuenta que ahora obtengo una opción seleccionada que sería el segundo elemento de la lista.

Aquí está mi ViewModel solo para unir todo:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVCProject.Models.ViewModels.Service { public class ServiceViewModel : ViewModel { public List IsMultipleServicers { get; set; } } } 

Aquí está mi acción:

 [AcceptVerbs(HttpVerbs.Get)] public virtual ActionResult Service() { return View(new ServiceViewModel() { IsMultipleServicers = BuildBooleanSelectList(true) }; } private List BuildBooleanSelectList(bool isTrue) { List list = new List(); if (isTrue) { list.Add(new SelectListItem() { Selected = false, Text = "No", Value = "false" }); list.Add(new SelectListItem() { Selected = true, Text = "Yes", Value = "true" }); } else { list.Add(new SelectListItem() { Selected = true, Text = "No", Value = "false" }); list.Add(new SelectListItem() { Selected = false, Text = "Yes", Value = "true" }); } return list; } 

Creo que el problema es una confusión con respecto a las sobrecargas DropDownList :

  1. Html.DropDownList(string name) busca una propiedad de modelo de vista de name y tipo IEnumerable . Utilizará el elemento seleccionado ( SelectListItem.Selected == true ) de la lista, a menos que exista un valor de publicación de formulario con el mismo nombre.

  2. Html.DropDownList(string name, IEnumerable selectList) usa los elementos de selectList , pero no sus valores seleccionados. El seleccionado se encuentra resolviendo el name en el modelo de vista (o datos de publicación) y haciendo coincidirlo con SelectListItem.Value . Incluso si el valor no se puede encontrar (o es nulo), aún no usará el valor seleccionado de la lista de SeleccionarListaItems.

Su código usa la segunda sobrecarga, pero especifica una propiedad de “valor” que no existe (“MultipleServicers”).

Para solucionar su problema, use la primera sobrecarga:

 <%= Html.DropDownList("IsMultipleServicers") %> 

O bien, agregue una propiedad string MultipleServicers a su modelo de vista y rellene en su controlador. Recomendaría esta solución ya que soluciona varios problemas con la visualización inicial, la visualización de publicaciones y el mapeo de los datos de la publicación en un modelo de vista / publicación:

 public class ServiceViewModel : ViewModel { public string MultipleServicers { get; set; } public List IsMultipleServicers { get; set; } } 

Entonces para tu HTML:

 <%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %> 

Esta técnica se mapea en MVC2, también:

 <%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %> 

Encontré este mismo problema usando la sobrecarga Html.DropDownList (nombre de cadena, IEnumerable selectList). Parece que mi modelo tiene una propiedad con el mismo nombre que el nombre de la lista desplegable. Siendo este el caso, MVC favoreció el valor de propiedad de mi modelo sobre la propiedad seleccionada de cada entrada en IEnumerable.

La solución fue usar un nombre para la lista desplegable que no coincide con un nombre de propiedad. Otra solución sería escribir mi propio método de extensión que ignora el estado del modelo y de la vista y en su lugar siempre respeta la propiedad seleccionada.

El ayudante DropDownList extrae el valor predeterminado del modelo. En el primer caso, el valor en el modelo correspondiente al nombre es una lista de selección – esto no coincide con ninguno de los elementos en la lista, es la lista, por lo que no se elige ningún valor. En el segundo ejemplo, su modelo no incluye una propiedad con ese nombre, por lo que no se puede usar el valor del modelo y se establece de manera predeterminada en el estado indicado en la lista Select. Normalmente, tendré una propiedad en el modelo para el valor seleccionado, esto se convierte en el valor predeterminado, y otra propiedad que representa los valores potenciales para la lista.