我有一个视图,它根据List<decimal>
类型的视图模型属性的长度创建了许多输入框。
我使用带索引的for循环将输入绑定到列表。这工作正常,用户输入的值传递给POST方法确定。以下代码工作正常(例如3个输入,值为1,2和3,然后是MyList = [1,2,3]
):
@for (var i = 0; i < Model.MyList.Count; i++)
{
<input asp-for="MyList[i]" type="text">
}
但是,我需要将第一个输入框的禁用状态设置为“禁用”。如果我按如下方式添加if语句,则绑定不起作用,MyList属性为空,计数为零。 (例如2个输入 - 第一个是只读的 -
值为2和3然后MyList = []
。我预先在控制器中填充第一个输入框,值为1,所以我希望得到MyList = [1,2,3]
,但我没有。)
@for (var i = 0; i < Model.MyList.Count; i++)
if (i == 0)
{
<input asp-for="MyList[i]" type="text" disabled="disabled">
}
else
{
<input asp-for="MyList[i]" type="text">
}
}
为简洁起见,代码已经归结为最低
为什么这个if语句会破坏绑定,或者如何绕过这个?谢谢你的阅读!
编辑:我尝试在循环之前和之外渲染第一个输入,然后在索引为1时启动循环,但是会出现同样的问题。
更新:我可以通过使用jQuery轻松地将禁用状态设置为true,但这也会杀死属性。因此,禁用的任何绑定输入都是清除MyList。
答案 0 :(得分:1)
DefaultModelBinder
要求集合索引器开始为零并且是连续的(除非您为集合索引器添加输入)。
禁用控件不提交值,因此当您禁用第一个输入时,第一个项目的索引器为1
,而不是0
,因此模型绑定失败。
解决此问题的一种简单方法是使输入只读
<input asp-for="MyList[i]" type="text" readonly="readonly">
另一种选择是为集合索引器包含一个隐藏输入,它允许在索引器不是从零开始连续的情况下绑定集合。
@for (var i = 0; i < Model.MyList.Count; i++)
if (i == 0)
{
<input asp-for="MyList[i]" type="text" disabled="disabled">
}
else
{
<input asp-for="MyList[i]" type="text">
}
<input type="hidden" name="MyList.Index" value="@i" />
}
但请注意,在这种情况下,集合将缺少第一个项目(因为将不提交已禁用输入的值)。