【问题标题】:Model not being updated when using a List使用列表时模型未更新
【发布时间】:2015-07-14 21:04:36
【问题描述】:

我有一个具有 List 类型属性的模型。我使用此属性在我的视图中显示值。我使用 foreach 循环遍历列表中的每个项目并使用 DisplayFor 和 TextBoxFor 显示它们。那部分工作正常;我之前使用过 TextBoxFor,任何用户输入的文本都会在提交时传递给模型。但是,使用列表时,提交表单时列表为空。模型中的所有其他属性都已更新,我可以正确访问它们。是什么阻止了列表绑定,我该如何解决?

ModelInstrumentListingDetail

public class ModelInstrumentListingDetail
{
    public int InstrumentTagID { get; set; }
    public string InstrumentTagDescription { get; set; }

    public List<ModelInstrumentListingItem> items { get; set; }
}

ModelInstrumentListingItem

public class ModelInstrumentListingItem
{
    public string Field { get; set; }
    public string Label { get; set; }
}

查看

@model GPC.Models.ModelInstrumentListingDetail

@using (Html.BeginForm("InstrumentListingAdd", "Home", FormMethod.Post, new { id = "InstrumentListingDetailForm" }))
{
  <table>
   <tr>
    <td>
         @Html.TextBoxFor(m => m.InstrumentTagDescription)
    </td>
   </tr>

  @foreach (GPC.Models.ModelInstrumentListingItem item in Model.items)
  {
   <tr>
      <td>
          @Html.DisplayFor(m => item.Label)
      </td>
      <td>
          @Html.TextBoxFor(m => item.Field)
      </td>
   </tr>
   }
</table>
<input id="submitInstrumentListingAdd" name="submitInstrumentListingAdd" value="Add" type="submit" class="SaveButton" />
}

控制器

[HttpPost]
public ActionResult InstrumentListingAdd(ModelInstrumentListingDetail model, string submitInstrumentListingAdd)
{
  ...
}

提交时,发布到控制器的模型具有带有值的 InstrumentDescription,但 items 为空。我需要弄清楚如何用新值填充项目。

【问题讨论】:

标签: c# asp.net-mvc asp.net-mvc-4 model-view-controller


【解决方案1】:

像这样改变循环:

@for(int idx = 0;idx < Model.items.Count;idx++)
{
    <tr>
         <td>
            @Html.DisplayFor(_ => Model.items[idx].Label)
         </td>
         <td>
             @Html.TextBoxFor(_ => Model.items[idx].Field)
         </td>
     </tr>
}

这样做的原因是&lt;input&gt; 元素将像这样生成:

&lt;input id="Items_0_" name="Items[0]" type="text" value="Foo"&gt; &lt;input id="Items_1_" name="Items[1]" type="text" value="Bar"&gt;

当您发布数据时,正文中将显示如下内容:

Items[0]:Foo
Items[1]:Bar

默认的 ASP.NET MVC 模型绑定器将从请求正文中选择这些 Items 并将它们应用于视图模型,在您的情况下为 ModelInstrumentListingDetail.items

【讨论】:

  • 这非常有效。非常感谢;你为我节省了几个小时的工作时间(以及我老板的很多悲伤)。给你几个问题: 1. 这似乎是一个“黑客”;这就是你必须在 MVC 中做事才能让它“正确”工作的方式吗? 2. 我们的办公室已经从asp.net转到MVC,这里没有人接受过MVC培训。我很想学习如何做这样的事情而不必发布问题并希望有人回答。我读过一些关于 MVC 的书,但它们通常只展示基础知识。你能推荐一些资源来让我学习你给我看的东西吗?
  • 不,这不是 hack,这是一种将项目发布到控制器的非常标准的方式,模型绑定器知道它们属于列表。至于资源——我对 MVC 的了解大部分来自 StackOverflow。我提出问题并查看了 Darin Dimitriov stackoverflow.com/users/29407/darin-dimitrov 给出的答案,我从他的回答中学到了很多东西。很高兴我能帮忙:)
【解决方案2】:

如果你想正确绑定你的列表,你应该使用EditorTemplatesEditorFor 助手或for 循环。 Here is an example.

如果你将使用for 循环,它应该是这样的:

  @for (int i = 0; i< Model.items.Count(); i++)
  {
   <tr>
      <td>
          @Html.DisplayFor(m => Model.items[i].Label)
      </td>
      <td>
          @Html.TextBoxFor(m => Model.items[i].Field)
      </td>
   </tr>
   }

for 循环 - 简短的方法,但使用 EditorTemplate - 更干净的解决方案,所以 我推荐它

【讨论】:

  • 感谢您的回复。 for 循环完美运行。我尝试了 EditorTemplate,但它没有将值绑定到模型(当它到达控制器时,项目仍然为空)。我怀疑我需要使用项目索引和 EditorTemplate 的 for 循环(而不是 foreach)的某种组合。我也不完全确定我正确设置了 EditorTemplate。我设置了 ModelInstrumentListingItem 类型的 cshtml 视图,其中有一个用于 model.field 的文本框。然后我向 ModelInstrumentListingItem 添加了一个 UIHint。认为我需要在尝试使用 EditorTemplate 之前对其进行更多调查。
【解决方案3】:

我想我之前也遇到过类似的问题。

不妨试试:

[HttpPost]
public ActionResult InstrumentListingAdd([Bind(Prefix = "item")]ModelInstrumentListingItem model, string submitInstrumentListingAdd)
{
  ...
}

【讨论】:

  • 感谢您的回复。这对我不起作用。创建的 HTML 对每个输入标签使用相同的名称和 id。也许这就是它不起作用的原因?让他们使用不同的名字有什么想法吗?这是 HTML:
猜你喜欢
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
相关资源
最近更新 更多