DropDownListFor en EditorTemplate no selecciona valor

Tengo una plantilla de editor para un objeto personalizado. Dentro de esa plantilla de editor utilizo un par de DropDownListFor helpers. En cada uno de ellos especifico una propiedad de modelo única (con el valor preseleccionado) y la lista de selección que contiene todas las opciones de selección.

Ejemplo:

 m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

Sé que los valores de las opciones se están rellenando (desde la fuente de visualización) y que mi modelo se transfiere con el valor de ID correcto (DocumentCategoryType).

Cuando se representa la vista, no hay ningún elemento seleccionado en mi menú desplegable y, por lo tanto, se establece de manera predeterminada en el primer valor (no seleccionado).

¿Alguien tiene alguna idea?

Gracias.

También SelectList la solución completando una nueva lista de SelectList que tiene seleccionado el elemento SelectListItem , pero creamos este método de extensión para mantener la llamada a DropDownListFor un poco más limpio:

 public static SelectList MakeSelection(this SelectList list, object selection) { return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection); } 

Entonces su llamada DropDownListFor convierte en:

 <%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %> 

Mirar a través del código fuente de ASP.NET MVC 2 revela algunas soluciones a este problema. Esencialmente, cualquier SelectListItem en SelectList pasado en el método de extensión auxiliar que tiene la propiedad Selected establecida en true no tiene ninguna influencia sobre el elemento representado con el atributo selected aplicado para el elemento.

El atributo selected en los elementos está determinado por

1) verificar que el método de extensión auxiliar fue pasado a SelectList . Si esto es nulo, el marco buscará en ViewData un valor correspondiente a la clave que es la propiedad del modelo de vista para la que desea representar la lista desplegable. Si el valor es una lista de SelectList , se usará para hacer que la incluya tomar cualquier valor seleccionado, siempre que el estado del modelo para la propiedad del modelo sea nulo.

2) Si se ha pasado una SelectList en el método de extensión auxiliar y el estado del modelo para la propiedad del modelo es nulo, la estructura buscará en el ViewData un valor predeterminado, utilizando el nombre de la propiedad del modelo como la clave. El valor en los datos de vista se convierte en una cadena y cualquier elemento en la lista de SelectList transfiera al método de extensión auxiliar que tenga un valor (si no se establece ningún valor, se marcará el texto) que coincida con el valor predeterminado tendrá la propiedad Selected se establece en verdadero, que a su vez representará una con el atributo selected="selected" .

Al unir esto, hay dos opciones plausibles que puedo ver para tener una opción seleccionada y usar DropDownListFor fuertemente tipado:

Usando el siguiente modelo de vista

 public class CategoriesViewModel { public string SelectedCategory { get; private set ; } public ICollection Categories { get; private set; } public CategoriesViewModel(string selectedCategory, ICollection categories) { SelectedCategory = selectedCategory; Categories = categories; } } 

Opción 1

Establezca un valor en ViewData en el controlador que represente su vista con el nombre de propiedad de la colección utilizada para representar el menú desplegable

la acción del controlador

 public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); this.ViewData["Categories"] = selectedCategory; return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } } 

y en la vista fuertemente tipada

 <%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %> 

opcion 2

Renderice el menú desplegable usando el nombre de la propiedad de los elementos seleccionados

la acción del controlador

 public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } } 

y en la vista fuertemente tipada

 <%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %> 

Se confirma como un error @ aspnet.codeplex.com y solo se comporta así para vistas fuertemente tipadas.

Solución alternativa: llene su lista de selección en el código de vista

me gusta

 <%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) => 

Yuck. Terminé resolviéndolo así. Espero que esto se arregle para RTM.

  <%if(Model!=null){ %> <%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%> <%}else{%> <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> <%}%> 

Asegúrese de tener un valor asignado a m.DocumentCategoryType cuando lo envíe a la vista.

En general, este valor se restablecerá cuando haga una publicación posterior, de modo que solo necesita especificar el valor cuando regrese a su vista.

Al crear una lista desplegable, debe pasarle dos valores. 1. Aquí es donde almacenará el valor seleccionado 2. ¿Es la Lista real?

Ejemplo

 <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

Cometí el error de establecer el elemento de la lista de selección Valor seleccionado en Verdadero. Esto no hará nada. En su lugar, simplemente asigne un valor a m.DocumentCategoryType en su controlador y esto realmente hará la selección por usted.

Aquí hay otra buena solución si la fuente de su lista desplegable es un IEnumerable en lugar de una SelectList:

 public static SelectList MakeSelection(this IEnumerable list, object selection, string dataValueField = "Value", string dataTextField = "Text") { return new SelectList(list, dataValueField, dataTextField, selection); } 
 Model.DocumentCategoryTypeList 

Este es probablemente tu problema. En SelectListItems, ¿establece el valor para el resultado .ToString ()?

  var list = new List() { new SelectListItem() { Value = Category.Book.ToString(), Text = "Book" }, new SelectListItem() { Value = Category.BitsAndPieces.ToString(), Text = "Bits And Pieces" }, new SelectListItem() { Value = Category.Envelope.ToString(), Text = "Envelopes" } }; 

Funciona para mí después de hacer eso. Solo necesita poder hacer coincidir el valor del objeto

Logré resolver el mismo problema diciendo lo siguiente:

 new SelectList(sections.Select(s => new { Text = s.SectionName, Value = s.SectionID.ToString() }), "Value", "Text") 

Este truco consiste en convertir el valor en una cadena. Sé que esto ha sido mencionado en respuestas anteriores, pero mi solución me parece un poco más limpia :). Espero que esto ayude.

Copiado na pegado de mi proyecto:

 <%= Html.DropDownListFor(m => m.Profession.Profession_id, new SelectList(Model.Professions, "Profession_id", "Profession_title"),"-- Profession --")%> 

Modelo que se pasa:

  ... public Profession Profession { get; set; } public IList Professions { get; set; } ... 

Html generado:

   

Funciona para mi. Tengo esto en el formulario y la única desventaja es que si el modelo no es válido y devuelvo el modelo a la vista, tengo que volver a cargar la lista de profesiones.

 obj.Professions = ProfileService.GetProfessions(); return View(obj); 

También tuve este problema con un campo ProgramName. Resulta que utilizamos ViewBag.ProgramName en BaseController y Layout.cshtml, y esto fue para un propósito diferente. Dado que el valor en ViewBag.ProgramName no se encontró en la lista desplegable, no se seleccionó ningún valor aunque SelectListItem.Selected era verdadero para un elemento de la lista. Acabamos de cambiar el ViewBag para usar una clave diferente y el problema se resolvió.

Aquí hay un drop-in DropDownListFor reemplazo que varía solo ligeramente de la fuente MVC original.

Ejemplo:

 <%=Html.FixedDropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

Estaba preocupado por la realización de hacer tantas copias de mi lista de selección, así que en su lugar, agregué el valor seleccionado como un atributo personalizado, luego usé jquery para realizar la selección del elemento:

 @Html.DropDownListFor(item => item.AttendeeID, attendeeChoices, String.Empty, new { setselectedvalue = Model.AttendeeID }) ........ jQuery("select[setselectedvalue]").each(function () { e = jQuery(this); e.val(e.attr("setselectedvalue")); });