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?

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

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.


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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.