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ć?

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

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.


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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.