扩展方法无法进行动态分派

124

我希望在MVC中使用DropDownListFor

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

在控制器中

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

但我收到了这个错误:

'System.Web.Mvc.HtmlHelper<System.Collections.Generic.IEnumerable<Cinemavaadabiat.ViewModel.ArticleWriter_ViewModel>>' 没有可用的方法名为 'DropDownListFor',但似乎有一个同名的扩展方法。扩展方法无法动态分派。考虑将动态参数强制转换或使用非扩展方法语法调用扩展方法。

我不理解这个错误,我该检查什么?

3个回答

215

您正在使用扩展方法中的动态类型,这是不支持的。

将动态类型强制转换为实际类型,它就可以正常工作。

根据我现在所看到的,我会说:

(string) ViewBag.MagNo

这将导致

@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
无法将类型为“string”的值转换为“int”类型。 - nnmmss
3
@nnmmss,那么ViewBag.MagNo不是一个整数,而是一个字符串。将其转换为字符串,你就可以得到正确的结果了。 - bas
这个答案实际上并没有解决真正的问题——代码在其他项目中可以正常工作,而不需要进行强制转换,只是在他的项目中出现了问题——很可能是缺少某些配置,导致编译器混淆。——编辑:看起来@mkaj的答案解决了实际问题。 - BrainSlugs83
我能将 ViewBag.MagNo 强制转换为 bool? 类型吗? - Dylan Czenski
我传递了一个整数。最终我做的是(string)ViewBag.MyNumber.ToString()。只是添加ToString()或(string)会抛出异常。是的,我也觉得很奇怪。 - SZT

47

我解决这个问题的方法是添加:

    @model MyModel

在部分控件的顶部。我已经忘记了它。


谢谢,我正在将我的视图迁移到其他项目中,但是我忘记了@model,谢谢! - rochasdv
5
如果您使用大写的@Model而不是小写的model,您也会收到此错误。 - Timothy Kanski
你能详细解释一下吗?在这个上下文中,“MyModel”是指什么?你所提到的“partial control”是什么? - Kris Craig

5

在扩展MVC方法的主题上(这也是我遇到这个问题的原因),我喜欢使用Dapper的connection.Query()语法,它将结果作为IEnumerable<dynamic>返回。

同时,也可以通过以下方式使用动态对象:

  • Calling the static method directly, per Jon Skeet's answer:

    @model IEnumerable<dynamic>
    
    @PartialExtensions.Partial(Html, "~/link/to/_partialView.cshtml", Model)
    
  • Wrapping it in a class.

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

    Then in your MVC View:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接