Metody rozszerzające nie mogą być wysyłane dynamicznie

114

Chcę mieć DropDownListFor w 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" })   
}

w kontrolerze

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);
}

ale otrzymuję ten błąd

System.Web.Mvc.HtmlHelper<System.Collections.Generic.IEnumerable<Cinemavaadabiat.ViewModel.ArticleWriter_ViewModel>>” nie ma odpowiedniej metody o nazwie „ DropDownListFor”, ale wygląda na to, że ma metodę rozszerzenia o tej nazwie. Metody rozszerzające nie mogą być wysyłane dynamicznie. Rozważ rzutowanie dynamicznych argumentów lub wywołanie metody rozszerzenia bez składni metody rozszerzenia.

Nie rozumiem błędu, co mam to sprawdzić?

nnmmss
źródło

Odpowiedzi:

199

Używasz typów dynamicznych w metodach rozszerzających, które nie są obsługiwane.

Przerzuć typy dynamiczne na rzeczywiste i zadziała.

Z tego, co teraz widzę, powiedziałbym:

(string) ViewBag.MagNo

Co by skutkowało

@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" })   
}
bas
źródło
2
jest napisane, że nie można przekonwertować typu „string” na „int”
nnmmss
3
@nnmmss, a następnie ViewBag.MagNo nie jest intem, ale ciągiem znaków. Rzuć go na sznurek i powinieneś być złoty
bas
Ta odpowiedź tak naprawdę nie rozwiązuje prawdziwego problemu - kod działa w innych projektach bez rzutowania, po prostu nie w jego - prawdopodobnie brakuje jakiejś konfiguracji i powoduje to zamieszanie kompilatora. - Edycja: wygląda na to, że odpowiedź @ mkaj dotyczy rzeczywistego problemu.
BrainSlugs83
Czy mogę rzutować ViewBag.MagNona bool?typ?
Dylan Czenski
Przekazywałem liczbę całkowitą. Co ostatecznie zrobiłem (string) ViewBag.MyNumber.ToString (). Samo dodanie ToString () lub (string) zgłasza wyjątek. Tak, też to wydało mi się dziwne.
SZT
44

Moją poprawką dla tego problemu było dodanie:

    @model MyModel

U góry częściowej kontroli. Zapomniałem o tym.

mkaj
źródło
Dzięki, migrowałem swoje widoki do innego projektu i zapomniałem @model, dzięki!
rochasdv
3
Ten błąd pojawia się również, jeśli używasz wielkich liter @Model zamiast modelu małych liter.
Timothy Kanski
5

Aby rozwinąć temat metod rozszerzających MVC (i tak natknąłem się na to pytanie), lubię używać connection.Query()składni Dappera, która zwróci wyniki jako plik IEnumerable<dynamic>.

Możliwe jest również wykorzystanie obiektów dynamicznych poprzez:

  • Bezpośrednie wywołanie metody statycznej, zgodnie z odpowiedzią Jona Skeeta :

    @model IEnumerable<dynamic>
    
    @PartialExtensions.Partial(Html, "~/link/to/_partialView.cshtml", Model)
  • Pakowanie w klasę.

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

    Następnie w widoku MVC:

    @model Namespace.DynamicQueryResult
    
    @Html.Partial("~/link/to/_partialView.cshtml", Model)
Jason
źródło