web-dev-qa-db-fra.com

Il n'y a pas d'élément ViewData de type 'IEnumerable <SelectListItem>' ayant la clé 'xxx'

Il y a quelques articles à ce sujet sur Stack Overflow, mais aucun avec une réponse qui semble résoudre le problème dans ma situation actuelle.

J'ai une page avec un tableau, chaque ligne contient un certain nombre de champs de texte et une liste déroulante. Toutes les listes déroulantes doivent utiliser les mêmes données SelectList. Je les ai donc configurées comme suit:

contrôleur

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

Voir

<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>

J'ai utilisé exactement cette configuration dans de nombreux endroits, mais pour une raison quelconque, dans ce cas particulier, le message d'erreur suivant s'affiche:

Il n'y a pas d'élément ViewData de type 'IEnumerable' ayant la clé 'submarket_0'.

84
Jimbo

Ok, la réponse a donc été tirée d’autres publications sur ce problème:

Si votre ViewData contient un SelectList portant le même nom que votre DropDownList c'est-à-dire "submarket_0", l'assistant HTML renseignera automatiquement votre DropDownList avec ces données - si vous ne spécifiez pas le second paramètre, qui est dans ce cas la source SelectList.

Qu'est-il arrivé avec mon erreur était:

Parce que la table contenant les listes déroulantes était dans une vue partielle et que le ViewData avait été modifié et ne contenait plus le SelectList que j’avais référencé, le HtmlHelper (au lieu de lancer une erreur) a essayé de trouver la liste de sélection appelée "submarket_0" dans la ViewData (GRRRR !!!) qu’elle ne pouvait TOUJOURS pas trouver, puis a lancé une erreur à ce sujet :)

Corrigez-moi si j'ai tort, s'il-vous plait

76
Jimbo

Vieille question, mais voici une autre explication du problème. Vous obtiendrez cette erreur même si vous avez fortement typé les vues et n'utilisez pas ViewData pour créer votre liste déroulante. La raison de l'erreur peut devenir claire lorsque vous regardez le source 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;
}

Donc, si vous avez quelque chose comme:

@Html.DropDownList("MyList", Model.DropDownData, "")

Et Model.DropDownData Est nul, MVC cherche dans votre ViewData quelque chose nommé MyList et lève une erreur s'il n'y a aucun objet dans ViewData portant ce nom.

27
hawkke

J'ai eu la même erreur, je pense que le problème est que le texte de l'erreur est déroutant, car il donne un faux nom de clé.

Dans votre cas, il devrait indiquer "Aucun élément ViewData de type" IEnumerable "ne contient la clé" Sous-marchés "".

Mon erreur était une faute de frappe dans le code de vue (vos "sous-marchés"), mais le texte de l'erreur m'a rendu fou.

Je publie cette réponse parce que je veux dire aux gens qui recherchent cette erreur, comme moi, que le problème est que ce n'est pas de trouver l'innombrable, mais dans le var que c'est supposé le chercher ("Submarkets" dans dans ce cas), pas dans celui affiché en erreur ("submarket_0").

La réponse acceptée est très intéressante, mais comme vous l'avez dit, la convention est appliquée si vous ne spécifiez pas le deuxième paramètre. Dans ce cas, il a été spécifié, mais la variable var n'a pas été trouvée (dans votre cas, car viewdata ne l'avait pas, dans mon cas car J'ai mal orthographié le nom de la variable)

J'espère que cela t'aides!

15
Peto

Le problème est dû au post-retour qui se produit lorsque vous cliquez sur le bouton Envoyer. Ainsi, lors de la publication des données lors de la soumission, cliquez à nouveau avant de renvoyer View ().

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
8
rakesh

Vérifiez l'espace de noms.

Vous pouvez affecter System.Web.Webpages.Html.SelectListItem dans le contrôleur au lieu de System.Web.Mvc.SelectListItem.

3
MovGP0

C'est OK aussi; Par exemple:
==> Dans le fichier "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();
}

==> Dans le fichier View (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>

Maintenant, si nous supprimons cette déclaration:

ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);

à partir de l'arrière de la déclaration suivante (dans notre contrôleur):

return View();

nous verrons cette erreur:

Il n'y a pas d'élément ViewData de type 'IEnumerable' ayant la clé 'OperatorId'.

* Alors soyez sûr de l'existant de ces déclarations. *

1
Morteza

Dans mon cas, j'ai constaté que je définissais la méthode de publication comme privée à tort. après avoir changé privé à public.

[HttpPost]
private async Task<ActionResult> OnPostRemoveForecasting(){}

changer à

[HttpPost]
public async Task<ActionResult> OnPostRemoveForecasting(){}

Maintenant fonctionne bien.

0
Mohammed Sabbir

Pour moi, le problème à l'origine de cette erreur s'est produit lors de l'enregistrement d'une nouvelle ligne dans la base de données, mais un champ était nul. Dans la conception de la table de base de données, ce champ n'est pas null. Ainsi, lorsque j'ai essayé de sauvegarder une nouvelle ligne avec une valeur null pour un champ non null, Visual Studio a lancé cette erreur. Ainsi, je me suis assuré qu'une valeur était affectée au champ et que le problème était résolu.

0
Thuy