Os métodos de extensão não podem ser despachados dinamicamente

114

Eu quero ter DropDownListFor em 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" })   
}

no controlador

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

mas eu recebo este erro

' System.Web.Mvc.HtmlHelper<System.Collections.Generic.IEnumerable<Cinemavaadabiat.ViewModel.ArticleWriter_ViewModel>>' não tem nenhum método aplicável chamado ' DropDownListFor', mas parece ter um método de extensão com esse nome. Os métodos de extensão não podem ser despachados dinamicamente. Considere lançar os argumentos dinâmicos ou chamar o método de extensão sem a sintaxe do método de extensão.

Não consigo entender o erro, o que devo verificar?

nnmmss
fonte

Respostas:

199

Você está usando tipos dinâmicos em métodos de extensão, o que não é compatível.

Converta os tipos dinâmicos em tipos reais e funcionará.

Pelo que vejo agora, diria:

(string) ViewBag.MagNo

O que resultaria em

@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
fonte
2
diz Não é possível converter o tipo 'string' em 'int'
nnmmss
3
@nnmmss then ViewBag.MagNo não é um int, mas uma string. Lance-o em um barbante e você estará dourado
bas
Essa resposta realmente não aborda o problema real - o código funciona em outros projetos sem conversão, apenas não no dele - provavelmente há alguma configuração faltando e está fazendo com que o compilador fique confuso. - Editar: parece que a resposta de @mkaj aborda o problema real.
BrainSlugs83 de
Posso transmitir ViewBag.MagNopara um bool?tipo?
Dylan Czenski de
Eu estava passando um número inteiro. O que acabei fazendo (string) ViewBag.MyNumber.ToString (). Apenas adicionar ToString () ou (string) lança uma exceção. Sim, eu também achei isso estranho.
SZT
44

Minha solução para esse problema foi adicionar:

    @model MyModel

No topo do controle parcial. Eu tinha me esquecido disso.

mkaj
fonte
Obrigado, estava migrando minhas visualizações para outro projeto e esqueci o @model, thks!
rochasdv
3
Você também obterá este erro se usar @Model em maiúsculas em vez do modelo em minúsculas.
Timothy Kanski
5

Para expandir o assunto dos métodos de extensão MVC (que é como encontrei esta questão), gosto de usar a connection.Query()sintaxe de Dapper, que retornará resultados como um IEnumerable<dynamic>.

Também é possível usar objetos dinâmicos:

  • Chamando o método estático diretamente, de acordo com a resposta de Jon Skeet :

    @model IEnumerable<dynamic>
    
    @PartialExtensions.Partial(Html, "~/link/to/_partialView.cshtml", Model)
  • Envolvendo-o em uma classe.

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

    Em seguida, em seu MVC View:

    @model Namespace.DynamicQueryResult
    
    @Html.Partial("~/link/to/_partialView.cshtml", Model)
Jason
fonte