真的可以在这里使用另一组眼睛,我做错了什么?
型号:
public class reqView {
public string Name { get; set; }
/* Loads of properties */
private lsAddress _addresses = new lsAddress {
new Address { id = 1 }, new Address { id = 2 }
};
public lsAddress lsAddress {
get { return _addresses; }
set { _addresses = value; }
}
}
查看:
@Html.DropDownListFor(model => model.lsAddress[1].addrCC,
new SelectList(CacheConfig.Countries.Where(c => c.dix.Contains(Model.dix)), "id", "text", Model.lsAddress[1].addrCC),
new {@class = "form-control"} as object);
控制器:
public ActionResult Index() {
var model = (reqView) TempData["reqView"];
if (model == null) model = new reqView();
TempData["reqView"] = model;
return View(model);
}
lsAddress:
public class lsAddress : List<Address>, IEnumerable<SqlDataRecord>{
IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
{
var sqlRow = new SqlDataRecord(
new SqlMetaData("id", System.Data.SqlDbType.TinyInt, false, true, SortOrder.Unspecified, -1),
new SqlMetaData("nmContact", System.Data.SqlDbType.NVarChar, 80)
);
foreach (Address obj in this)
{
sqlRow.SetValue(0, obj.id);
sqlRow.SetValue(1, obj.cName);
yield return sqlRow;
}
}
}
要复制: 见.net fiddle 选择1然后2 - &gt;指数超出范围 选择2然后1 - >;对象引用未设置为对象的实例。
我在这里缺少什么?
答案 0 :(得分:1)
问题在于:如何在提交时绑定模型属性。
1)你在构造函数中初始化_addresses
,所以如果在提交时你没有传递这个属性的值,那么默认情况下这将是:带有两个元素的列表。
这就是为什么当您从0
变体提交时所有内容都有效:您将已禁用属性设置为选择,并在提交时未提供此值。
2)当你提交来自&#39; 1&#39 ;: select - enabled,并且具有映射到_addresses
的第一个元素的名称时,MVC会从请求来看到字段,并替换列表with to element,它是在构造函数中创建的,用于列出来自请求的on元素。
这就是你1
工作的原因,但是如果你看到他发送的内容 - 你会看到_addresses
列出一个元素的模型。这就是为什么从1
转到2
时出错的原因 - 您只需发送包含一个元素的列表,但在视图中尝试从index = 1的元素获取值而不是0。
3)当您从2
提交时:select也启用并且具有映射到_addresses
的第一个元素的名称,但MVC无法从一个元素创建正确的列表,索引为不是0如果你看到post方法中的内容,你可以看到_addresses
来 null 。
对于解决方案,您可以添加隐藏字段,这将是其他列表项的保存值:
@{var cur = -1;}
@switch (Model.dix)
{
case 0:
@Html.DropDownListFor(model => model.lsAddress[0].addrCC,
new SelectList(mvc.Controllers.CacheConfig.Countries.Where(c => c.dix.Contains(Model.dix)), "id", "text", Model.lsAddress[0].addrCC),
new { @class = "form-control", disabled = "disabled" } as object)
break;
case 1:
@Html.DropDownListFor(model => model.lsAddress[0].addrCC,
new SelectList(mvc.Controllers.CacheConfig.Countries.Where(c => c.dix.Contains(Model.dix)), "id", "text", Model.lsAddress[0].addrCC),
new { @class = "form-control" } as object);
cur = 0;
break;
case 2:
@Html.DropDownListFor(model => model.lsAddress[1].addrCC,
new SelectList(mvc.Controllers.CacheConfig.Countries.Where(c => c.dix.Contains(Model.dix)), "id", "text", Model.lsAddress[1].addrCC),
new { @class = "form-control" } as object);
cur = 1;
break;
}
@for (int i = 0; i < Model.lsAddress.Count; i++)
{
if (i == cur) { continue; }
@Html.HiddenFor(model => model.lsAddress[i].addrCC)
}