No hay ningún elemento ViewData de tipo 'IEnumerable <SelectListItem>' que tenga la clave 'xxx'

87

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'.

Jimbo
fuente
1
¿Intentaste esto? <%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>DropDownList toma IEnumerable<SelectListItem>.
LukLed
@LukLed: así es como finalmente encontré la fuente del error :) ¡así como información de algunas otras publicaciones! Gracias
Jimbo
<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
Arvis
Encontré esto hoy y encontré que el segundo argumento en mi ayudante DropDownList era nulo, según el hallazgo a continuación de @jonathansewell.
Ken Palmer

Respuestas:

79

Ok, entonces la respuesta se derivó de algunas otras publicaciones sobre este problema y es:

Si su ViewDatacontiene un SelectListcon el mismo nombre que su, DropDownListes decir, "submarket_0", el asistente Html lo completará automáticamente DropDownListcon 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 ViewDatahabía cambiado y ya no contenía el SelectListque había mencionado, el HtmlHelper(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

Jimbo
fuente
104
Recibí este error porque mi colección de SelectListItems para la lista desplegable era nula, que creo que es el mismo problema que tuviste.
Jonathan Sewell
6
Para otros que se enfrenten a este problema, envuelva temporalmente su lista desplegable en una marca nula, por ejemplo, @if (ViewData ["Submarkets"]! = Null). Si la vista luego se procesa sin arrojar un error (y sin su lista desplegable), habrá identificado su problema. En este caso, el error "no ver elemento de datos" es muy engañoso.
GDB
Me encontré con esto usando un Ajax.ActionLink. Simplemente agregue el SelectList Getal ActionMethodque contiene la llamada Ajax.
apesta
¡Sí! Había cambiado el nombre de la lista que estaba pasando a ViewData desde el controlador y no lo había cambiado en la vista. ¡Ese es un mensaje de error terriblemente confuso!
neminem
1
@JonathanSewell gracias, gracias, gracias! Este era mi problema exacto.
johnw182
29

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.DropDownDataes nulo, MVC busca en su ViewData algo con nombre MyListy arroja un error si no hay ningún objeto en ViewData con ese nombre.

Hawkke
fuente
1
Hola, este también es mi problema, ¿Qué hacemos si la lista es nula? ¿Puedes sugerir algo?
transformer
4
@transformer Lo más fácil sería establecer Model.DropDownData en una lista vacía en lugar de nula. Si eso no es posible, puede modificar el marcado de su afeitadora para verificar si la lista es nula y, de ser así, generar una lista de selección vacía.
Hawkke
15

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!

Peto
fuente
9

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");
rakesh
fuente
3

Verifique el espacio de nombres.

Puede asignar System.Web.Webpages.Html.SelectListItem en el controlador, en lugar de System.Web.Mvc.SelectListItem .

MovGP0
fuente
1

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. *

Morteza
fuente
0

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.

Thuy
fuente
0

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.

Mohammed Sabbir
fuente
0

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.

sdfs
fuente
-1

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(...)
Soluciones IndieTech
fuente
1
A menos que mis ojos me engañan, no hay SelectListen System.Collections.Generic.
Erik Philips