C# 在MVC4中绑定控件ListBoxFor时获取错误
当我将C# 在MVC4中绑定控件ListBoxFor时获取错误,c#,asp.net-mvc,asp.net-mvc-4,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> lstDocI
“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;
}
}
//这是我绑定listboxfor的视图
@model clslistbox
@using (Html.BeginForm("AddEditSupplier", "Admin", FormMethod.Post))
{
@Html.ListBoxFor(model => model.id, new SelectList(Model.lstDocImgs, "documentid", "title"))
}
有人能看出原因吗?我认为这里表达式中属性的更改是一种转移注意力的行为,无论在哪种情况下都不起作用 更新 然而,在我的答案的最后,你可以看到一些可能不必要的详细说明,关于为什么你第一次没有得到一个错误 结束更新 您使用的是
ListBoxFor
,它用于为用户提供多个选择功能,但您试图将其绑定到一个int
属性,该属性不支持多个选择。(它需要是一个IEnumerable
,至少能够在MVC中默认绑定一个列表框)
我想您的意思是使用DropDownListFor
-即显示一个项目列表,其中只能选择一个
如果您实际上是在列表框中寻找单选语义,那么在MVC中就更难了,因为它的Html帮助程序完全围绕列表框进行多选。SO上的其他人提出了一个关于如何使下拉列表看起来像列表框的问题:
或者您可以自己为这样的列表框生成HTML
(更新)-可能不必要的详细说明(!)
第一次没有得到异常的原因可能是,生成HTML时,ModelState
中没有id
的值。下面是您感兴趣的反映的MVC源代码(来自SelectExtensions.SelectInternal
)(最后的GetSelectListWithDefaultValue
调用是异常的源代码):
首先请注意,控制变量allowMultiple
在您的情况下为true,因为您调用了ListBoxFor
selectList
是您创建并作为第二个参数传递的selectList
。MVC(不幸的是在某些情况下)所做的一件事是使用ModelState
修改重新显示视图时传递的选择列表,以确保在重新加载视图时重新选择通过POST在ModelState
中设置的值(当页面验证失败时,这很有用,因为您不会将值从ModelState
复制到基础模型,但页面仍应在选择时显示这些值)
因此,正如您在第一行中所看到的,您传递的表达式/字段的模型当前值从模型状态中提取出来;要么作为字符串数组,要么作为字符串。如果失败(返回null
),那么它将再次执行表达式(或类似内容)获取模型值。如果从中获取非空值,则调用SelectExtensions.GetSelectListWithDefaultValue
正如我所说,无论是Id
还是SupplierId
(因为它们必须是IEnumerable
)的情况下,您试图做的最终都不会起作用但是我相信当您使用Id
时,这个ModelState
->Eval
过程会产生一个空值,因此获取“调整后的”SelectList
的过程会被跳过-因此不会引发异常。当您使用SupplierId
时,情况就不是这样了,因为我敢打赌会出现异常此时,ModelState
中有一个值,或者ViewData.Eval
成功获取一个整数值
不引发异常与正常工作不一样
结束更新尝试将属性从int更改为int[]
public class SuppDocuments
{
public string Title { get; set; }
public int documentid { get; set; }
}
假设上面是用于绑定模型的类,请尝试更改documentid属性,如下所示
public class SuppDocuments
{
public string Title { get; set; }
public int[] documentid { get; set; }
}
谢谢,你知道它没有为model.id给出错误的原因吗答案似乎是正确的(而且合乎逻辑),但是为什么“某物”使用
model=>model.id
那么?有什么想法吗?是的,“某物”很重要。“某物”只是意味着没有例外吗?如果是这样,这还不足以将其归类为“工作”。@RaphaëlAlthaus:更新了答案,并解释了解释,我还注意到(测试)这两种解决方案都不“工作”,但无法理解为什么他们“工作方式不同”;)
public class SuppDocuments
{
public string Title { get; set; }
public int documentid { get; set; }
}
public class SuppDocuments
{
public string Title { get; set; }
public int[] documentid { get; set; }
}