awr*_*ley 7 asp.net-mvc asp.net-mvc-3 asp.net-mvc-scaffolding html.listboxfor
我使用MvcScaffolding搭建了一个控制器.
对于一个属性Model.IdCurrencyFrom,脚手架创建了一个Html.DropDownListFor:
@Html.DropDownListFor(model => model.IdCurrencyFrom,
((IEnumerable<FlatAdmin.Domain.Entities.Currency>)ViewBag.AllCurrencies).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.CurrencyName),
Value = option.CurrencyId.ToString(),
Selected = (Model != null) && (option.CurrencyId == Model.IdCurrencyFrom)
}), "Choose...")
Run Code Online (Sandbox Code Playgroud)
无论是使用新记录还是编辑现有记录,这都可以正常工作.
只有3种货币,AR $,US $和GB£.因此,我想要一个ListBox而不是下拉列表.
所以我把上面改为:
@Html.ListBoxFor(model => model.IdCurrencyFrom,
((IEnumerable<FlatAdmin.Domain.Entities.Currency>)ViewBag.AllCurrencies).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.CurrencyName),
Value = option.CurrencyId.ToString(),
Selected = (Model != null) && (option.CurrencyId == Model.IdCurrencyFrom)
}))
Run Code Online (Sandbox Code Playgroud)
我现在得到一个ArgumentNullException,参数名称:source,但仅在编辑现有记录时.创建新记录,这很好.
怎么了?!
什么也没有变.切换回DropDownListFor,一切正常.切换到ListBox(而不是ListBoxFor),我得到错误.
该模型不为null(就像我说的,它适用于DropDownListFor)...而且我的想法已经用完了.
我检查了HTML助手的来源,这是一个有趣的练习.
TL; DR; 问题是ListBoxFor用于多个选择,它需要一个可枚举的Model属性.您的Model属性(model.IdCurrencyFrom)不是可枚举的,这就是您获得异常的原因.
以下是我的发现:
ListBoxFor方法将始终select使用multiple="multiple"属性呈现元素.它是硬编码的System.Web.Mvc.Html.SelectExtensions
private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
return SelectInternal(htmlHelper, null /* optionLabel */, name, selectList, true /* allowMultiple */, htmlAttributes);
}
Run Code Online (Sandbox Code Playgroud)
所以也许你不管怎样也不想允许用户使用多种货币......
当此ListBoxHelper尝试从您的模型属性获取默认值时,您的问题开始:
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
Run Code Online (Sandbox Code Playgroud)
它适用于DropDownList,因为它allowMultiple在调用时传递false SelectInternal.
因为你ViewData.ModelState是空的(因为你的控制器之前没有发生任何验证)defaultValue将是null.然后defaultValue使用您的模型的默认值进行初始化(我的情况model.IdCurrencyFrom就是int这样),所以它会是0.:
if (!usedViewData) {
if (defaultValue == null) {
defaultValue = htmlHelper.ViewData.Eval(fullName);
}
}
Run Code Online (Sandbox Code Playgroud)
我们接近异常:)因为我提到ListBoxFor只支持多个选择,所以它试图处理defaultValue为IEnumbrable:
IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
Run Code Online (Sandbox Code Playgroud)
在第二行有你的ArgumentException,因为defaultValues是null.
因为它希望defaultValue是可枚举的,因为string是可枚举的.如果更改的类型model.IdCurrencyFrom,以string它的工作.但是,当然您将在UI上进行多项选择,但您只能获得模型中的第一个选择.
| 归档时间: |
|
| 查看次数: |
1570 次 |
| 最近记录: |