在MVC4中绑定ListBoxFor控件时获取错误

Dot*_*per 7 c# asp.net-mvc asp.net-mvc-4

当我改变时"model => model.id","model => model.Supplierid"我正在低于错误

"当允许多个选择时,参数'expression'必须求值为IEnumerable."

请看下面的代码

//这是我的模特课

public class clslistbox{
public int id { get; set; }
public int Supplierid { get; set; }
public List<SuppDocuments> lstDocImgs { get; set; }

public class SuppDocuments
{
    public string Title { get; set; }
    public int documentid { get; set; }
}
public List<SuppDocuments> listDocImages()
{
    List<SuppDocuments> _lst = new List<SuppDocuments>();
    SuppDocuments _supp = new SuppDocuments();
    _supp.Title = "title";
    _supp.documentid = 1;
    _lst.Add(_supp);
    return _lst;
} 
}
Run Code Online (Sandbox Code Playgroud)

//这是我的控制器

    [HttpGet]
    public ActionResult AddEditSupplier(int id)
    {

        clslistbox _lst = new clslistbox();
        _lst.lstDocImgs= _lst.listDocImages();
        return View(_lst);
    }
Run Code Online (Sandbox Code Playgroud)

//这是我绑定listboxfor的视图

@model clslistbox
@using (Html.BeginForm("AddEditSupplier", "Admin", FormMethod.Post))
{
    @Html.ListBoxFor(model => model.id, new SelectList(Model.lstDocImgs, "documentid", "title"))
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以看到它的原因吗?

And*_*tan 17

我认为这里表达式中属性的变化是一个红色的鲱鱼 - 在任何一种情况下都不会起作用.

更新

但是,在我的答案结尾处看到一些可能不必要的详细说明为什么你没有第一次得到错误.

结束更新

您正在使用ListBoxFor- 用于为用户提供多种选择功能 - 但您尝试将其绑定到int属性 - 这不支持多项选择.(它必须IEnumerable<T>至少能够在MVC中默认将列表框绑定到它)

我认为你的意思是使用DropDownListFor- 即显示一个项目列表,只能从中选择一个项目?

如果你实际上在列表框中寻找单选语义,那么在MVC中这样做比较棘手,因为它的Html助手完全适合用于多选的列表框.SO上的其他人问了一个关于如何让下拉列表看起来像列表框的问题:如何在ASP.NET MVC中使用单一选择模式创建ListBox?.

或者您可以自己为这样的列表框生成HTML.

(更新) - 潜在的不必要的详细说明(!)

究其原因,你没有得到一个例外,第一次轮可能是因为没有为没有价值idModelState被生成的HTML时.这SelectExtensions.SelectInternal是感兴趣的反射MVC源(来自)(最后的GetSelectListWithDefaultValue调用是您的异常的来源):

object obj = 
  allowMultiple ? htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string[])) : 
    htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string));
if (!flag && obj == null && !string.IsNullOrEmpty(name))
{
  obj = htmlHelper.ViewData.Eval(name);
}
if (obj != null)
{
  selectList = 
    SelectExtensions.GetSelectListWithDefaultValue(selectList, obj, allowMultiple);
}
Run Code Online (Sandbox Code Playgroud)

首先请注意,控件变量allowMultiple在您的情况下为真,因为您已调用ListBoxFor. selectListSelectList您创建并传递为第二个参数.MVC(遗憾的是在某些情况下)的作用之一是用于ModelState修改重新显示视图时传递的选择列表,以确保ModelState在视图为时重新选择通过POST 设置的值重新加载(这在页面验证失败时很有用,因为您不会将值复制到底层模型中ModelState,但页面仍然应该将这些值显示为已选中).

所以你可以在第一行看到,你传递的表达式/字段的模型当前值是从模型状态中捕获的; 要么是字符串数组,要么是字符串.如果失败(返回null),那么它会再次执行表达式(或类似的)来获取模型值.如果从那里获得非空值,则调用SelectExtensions.GetSelectListWithDefaultValue.

正如我所说的那样 - 你要做的事情最终都不会起作用Id或者SupplierId(因为它们需要IEnumerable)但是我相信这个ModelState- > Eval进程在你使用时会产生一个空值Id,所以获得的过程SelectList跳过'已调整' - 因此异常不会被提升.当你使用时,情况也是如此,SupplierId因为我会打赌ModelState在那一点上有一个值,或者ViewData.Eval成功获得一个整数值.

不抛出异常一样的工作!

结束更新