Les méthodes d'extension ne peuvent pas être distribuées dynamiquement


114

Je veux avoir DropDownListFor dans MVC

@foreach (var item in Model)
{
    @Html.DropDownListFor(modelItem => item.TitleIds, new SelectList(ViewBag.TitleNames as System.Collections.IEnumerable, "TitleId", "Title.TitleText"), "No: " + ViewBag.MagNo, new { id = "TitleIds" })   
}

dans le contrôleur

public ActionResult ArticleList(int id)
{
    ArticleWriter_ViewModel viewModel = new ArticleWriter_ViewModel();
    Func<IQueryable<NumberTitle>, IOrderedQueryable<NumberTitle>> orderByFunc = null;
    Expression<Func<NumberTitle, bool>> filterExpr = null;
    if (id > 0)
    {
        filterExpr = p => p.MagazineId.Equals(id);
    }
    var wholeTitles = unitOfWork.NumberTitleRepository.Get(filterExpr,  orderByFunc, "Magazine,Title").ToList();          

    ViewBag.MagNo = wholeTitles[0].Magazine.MagNo.ToString();
    ViewBag.MagId = wholeTitles[0].Magazine.Id;
    ViewBag.TitleNames = wholeTitles;

    return View("../Panel/Magazine/ArticleList", "_BasicLayout", viewModel);
}

mais j'obtiens cette erreur

« System.Web.Mvc.HtmlHelper<System.Collections.Generic.IEnumerable<Cinemavaadabiat.ViewModel.ArticleWriter_ViewModel>>» n'a pas de méthode applicable nommée « DropDownListFor» mais semble avoir une méthode d'extension de ce nom. Les méthodes d'extension ne peuvent pas être distribuées dynamiquement. Envisagez de convertir les arguments dynamiques ou d'appeler la méthode d'extension sans la syntaxe de la méthode d'extension.

Je ne comprends pas l'erreur, que dois-je vérifier?

Réponses:


199

Vous utilisez des types dynamiques dans les méthodes d'extension, ce qui n'est pas pris en charge.

Convertissez les types dynamiques en types réels, et cela fonctionnera.

D'après ce que je vois maintenant, je dirais:

(string) ViewBag.MagNo

Ce qui entraînerait

@foreach (var item in Model)
{
    @Html.DropDownListFor(modelItem => item.TitleIds, 
       new SelectList(ViewBag.TitleNames as System.Collections.IEnumerable, 
       "TitleId", "Title.TitleText"), 
       "No: " + (string) ViewBag.MagNo, 
       new { id = "TitleIds" })   
}

2
il dit Impossible de convertir le type 'string' en 'int'
nnmmss

3
@nnmmss alors ViewBag.MagNo n'est pas un entier, mais une chaîne. Lancez-le sur une chaîne et vous devriez être en or
bas

Cette réponse ne résout pas vraiment le vrai problème - le code fonctionne dans d'autres projets sans casting, mais pas dans le sien - il y a probablement une configuration manquante et cela cause la confusion du compilateur. - Modifier: On dirait que la réponse de @ mkaj résout le problème réel.
BrainSlugs83

Puis-je caster ViewBag.MagNoun bool?type?
Dylan Czenski

Je passais un entier. Ce que j'ai fini par faire (chaîne) ViewBag.MyNumber.ToString (). L'ajout de ToString () ou (string) lève une exception. Yah j'ai trouvé ça bizarre aussi.
SZT

44

Ma solution à ce problème était d'ajouter:

    @model MyModel

En haut du contrôle partiel. Je l'avais oublié.


Merci, je migrais mes vues vers un autre projet et j'ai oublié le @model, merci!
rochasdv

3
Vous obtenez également cette erreur si vous utilisez @Model majuscule au lieu du modèle minuscule.
Timothy Kanski

5

Pour développer le sujet des méthodes d'extension MVC (c'est ainsi que j'ai rencontré cette question), j'aime utiliser la connection.Query()syntaxe de Dapper qui retournera les résultats sous forme de fichier IEnumerable<dynamic>.

Il est également possible d'utiliser des objets dynamiques en:

  • Appel de la méthode statique directement, selon la réponse de Jon Skeet :

    @model IEnumerable<dynamic>
    
    @PartialExtensions.Partial(Html, "~/link/to/_partialView.cshtml", Model)
  • Emballer dans une classe.

    public class DynamicQueryResult
    {
        public dynamic QueryResults {get; set;}
    }

    Puis dans votre vue MVC:

    @model Namespace.DynamicQueryResult
    
    @Html.Partial("~/link/to/_partialView.cshtml", Model)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.