Hay un par de publicaciones sobre esto en Stack Overflow, pero ninguna con una respuesta que parezca solucionar el problema en mi situación actual.
Tengo una página con una tabla, cada fila tiene varios campos de texto y un menú desplegable. Todos los menús desplegables deben usar los mismos datos de SelectList, así que los configuré de la siguiente manera:
Controlador
ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
Ver
<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>
He usado exactamente esta configuración en muchos lugares, pero por alguna razón en esta vista en particular obtengo el error:
No hay ningún elemento ViewData de tipo 'IEnumerable' que tenga la clave 'submarket_0'.
<%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>
DropDownList tomaIEnumerable<SelectListItem>
.<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
Respuestas:
Ok, entonces la respuesta se derivó de algunas otras publicaciones sobre este problema y es:
Si su
ViewData
contiene unSelectList
con el mismo nombre que su,DropDownList
es decir, "submarket_0", el asistente Html lo completará automáticamenteDropDownList
con esos datos si no especifica el segundo parámetro, que en este caso es la fuente SelectList.Lo que pasó con mi error fue:
Debido a que la tabla que contiene las listas desplegables estaba en una vista parcial y se
ViewData
había cambiado y ya no contenía elSelectList
que había mencionado, elHtmlHelper
(en lugar de arrojar un error) intentó encontrar el SelectList llamado "submarket_0" en ViewData (GRRRR! !!) que TODAVÍA no pudo encontrar, y luego arrojó un error en eso :)Por favor corrígeme si estoy equivocado
fuente
Ajax.ActionLink
. Simplemente agregue elSelectList
Get
alActionMethod
que contiene la llamada Ajax.Antigua pregunta, pero aquí hay otra explicación del problema. Obtendrá este error incluso si tiene vistas fuertemente tipadas y no está usando ViewData para crear su lista desplegable. El motivo del error puede quedar claro cuando mira la fuente MVC :
// If we got a null selectList, try to use ViewData to get the list of items. if (selectList == null) { selectList = htmlHelper.GetSelectData(name); usedViewData = true; }
Entonces, si tienes algo como:
@Html.DropDownList("MyList", Model.DropDownData, "")
Y
Model.DropDownData
es nulo, MVC busca en su ViewData algo con nombreMyList
y arroja un error si no hay ningún objeto en ViewData con ese nombre.fuente
Tuve el mismo error, creo que el problema es que el texto del error es confuso , porque da un nombre de clave falso.
En su caso, debería decir "No hay ningún elemento ViewData de tipo 'IEnumerable' que tenga la clave" Submercados "".
Mi error fue un error ortográfico en el código de vista (sus "Submercados"), pero el texto del error me volvió loco.
Publico esta respuesta porque quiero decirles a las personas que buscan este error, como yo, que el problema es que no está encontrando el IENumerable, sino en la var que se supone que debe buscarlo ("Submarkets" en este caso), no en el que se muestra por error ("submercado_0") .
La respuesta aceptada es muy interesante, pero como dijiste, la convención se aplica si no especificas el segundo parámetro, en este caso se especificó, pero no se encontró la var (en tu caso porque los datos de vista no lo tenían, en mi caso porque Escribí mal el nombre de var)
¡Espero que esto ayude!
fuente
El problema se debe a que la publicación se produce al hacer clic en el botón Enviar. Entonces, mientras publica datos al enviar, haga clic nuevamente en escribir antes de regresar Ver ()
ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
fuente
Verifique el espacio de nombres.
Puede asignar System.Web.Webpages.Html.SelectListItem en el controlador, en lugar de System.Web.Mvc.SelectListItem .
fuente
Esto también está bien; Por ejemplo:
==> En el archivo "NumberController":
public ActionResult Create([Bind(Include = "NumberId,Number1,Number2,OperatorId")] Number number) { if (ModelState.IsValid) { ... ... return RedirectToAction("Index"); } ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId); return View(); }
==> Archivo en vista (Create.cshtml):
<div class="form-group"> @Html.LabelFor(model => model.Number1, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Number1, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Number1, "", new { @class = "text-danger" }) </div> </div>
Ahora, si eliminamos esta declaración:
ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);
desde la parte posterior de la siguiente declaración (en nuestro controlador):
return View();
veremos este error:
No hay ningún elemento ViewData de tipo 'IEnumerable' que tenga la clave 'OperatorId'.
* Así que asegúrese de la existencia de estas declaraciones. *
fuente
Para mí, el problema que causó este error surgió cuando estaba guardando una nueva fila en la base de datos, pero un campo era nulo. En el diseño de la tabla de la base de datos, ese campo NO es NULO. Entonces, cuando intenté guardar una nueva fila con un valor nulo para el campo no nulo, Visual Studio arrojó este error. Por lo tanto, me aseguré de que se asignara un valor al campo y se solucionó el problema.
fuente
En mi caso, descubrí que configuré el método de publicación como privado por error. después de cambiar de privado a público.
[HttpPost] private async Task<ActionResult> OnPostRemoveForecasting(){}
cambiar a
[HttpPost] public async Task<ActionResult> OnPostRemoveForecasting(){}
Ahora funciona bien.
fuente
La causa no es contraria a la sintaxis más que al uso inapropiado de objetos. El ciclo de vida de los objetos en ViewData, ViewBag y View Life Cycle es más corto que en la sesión. Los datos definidos en los formadores se perderán después de una solicitud-respuesta (si intenta acceder después de una solicitud-respuesta, obtendrá excepciones). Por lo tanto, los formadores son apropiados para pasar datos entre View y Controller, mientras que el último para almacenar datos temporales. Los datos temporales deben almacenarse en la sesión para que se pueda acceder a ellos muchas veces.
fuente
En mi caso, hubo un conflicto en los espacios de nombres, tengo:
using System.Web.Mvc;
y
using System.Collections.Generic;
Quiero explícitamente usar el Mvc, así que lo declaré como:
new System.Web.Mvc.SelectList(...)
fuente
SelectList
enSystem.Collections.Generic
.