Los métodos de extensión no se pueden distribuir dinámicamente

114

Quiero tener DropDownListFor en 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" })   
}

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

pero me sale este error

' System.Web.Mvc.HtmlHelper<System.Collections.Generic.IEnumerable<Cinemavaadabiat.ViewModel.ArticleWriter_ViewModel>>' no tiene un método aplicable llamado ' DropDownListFor' pero parece tener un método de extensión con ese nombre. Los métodos de extensión no se pueden distribuir dinámicamente. Considere convertir los argumentos dinámicos o llamar al método de extensión sin la sintaxis del método de extensión.

No entiendo el error, ¿qué debo verificar?

nnmmss
fuente

Respuestas:

199

Está utilizando tipos dinámicos en métodos de extensión, lo cual no es compatible.

Convierta los tipos dinámicos en tipos reales y funcionará.

Por lo que veo ahora, diría:

(string) ViewBag.MagNo

Lo que daría como resultado

@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
fuente
2
dice No se puede convertir el tipo 'cadena' a 'int'
nnmmss
3
@nnmmss entonces ViewBag.MagNo no es un int, sino una cadena. Tíralo a una cuerda y deberías ser dorado
bas
Esta respuesta realmente no aborda el problema real: el código funciona en otros proyectos sin conversión, pero no en el suyo; es probable que falte alguna configuración y esté causando confusión en el compilador. - Editar: parece que la respuesta de @ mkaj aborda el problema real.
BrainSlugs83
¿Puedo transmitir ViewBag.MagNoa un bool?tipo?
Dylan Czenski
Estaba pasando un número entero. Lo que terminé haciendo (cadena) ViewBag.MyNumber.ToString (). Simplemente agregar ToString () o (cadena) arroja una excepción. Sí, eso también me pareció extraño.
SZT
44

Mi solución para este problema fue agregar:

    @model MyModel

En la parte superior del control parcial. Lo había olvidado.

mkaj
fuente
Gracias, estaba migrando mis vistas a otro proyecto y olvidé el @modelo, ¡gracias!
rochasdv
3
También obtiene este error si usa @Model en mayúsculas en lugar de en minúsculas.
Timothy Kanski
5

Para ampliar el tema de los métodos de extensión MVC (que es cómo me encontré con esta pregunta), me gusta usar la connection.Query()sintaxis de Dapper, que devolverá los resultados como un IEnumerable<dynamic>.

También es posible utilizar objetos dinámicos mediante:

  • Llamar al método estático directamente, según la respuesta de Jon Skeet :

    @model IEnumerable<dynamic>
    
    @PartialExtensions.Partial(Html, "~/link/to/_partialView.cshtml", Model)
  • Envolviéndolo en una clase.

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

    Luego, en su Vista MVC:

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