如果循环包含if语句来控制输入呈现,则MVC视图不会在for循环中绑定输入

时间:2018-03-16 15:26:09

标签: razor asp.net-core-mvc

我有一个视图,它根据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。

1 个答案:

答案 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" />
}

但请注意,在这种情况下,集合将缺少第一个项目(因为将不提交已禁用输入的值)。