【问题标题】:Binding IEnumerable in ViewModel not working在 ViewModel 中绑定 IEnumerable 不起作用
【发布时间】:2017-08-12 23:08:22
【问题描述】:

我有一个 ViewModel - 客户。其中有一个 IEnumerable 集合:

public class Tag
{
    public int TagNo{ get; set; }
    public DateTime CreatedDate { get; set; }
}

我使用 foreach 将标签列表以及标量客户信息输出到页面:

...output customer info....
<div class="col-md-9">
    @{
        foreach (var Tag in Model.Tags)
        {
            @Html.DisplayFor(x => Tag.TagNo);
            <br />
        }
    }
</div>

我正在尝试在页面中隐藏模型绑定器的标签列表,因此我不需要再次访问数据库:

@{
    int[] tagArray = Model.Tags.Select(x => x.TagNo).ToArray();

    for (int i = 0; i < Model.Tags.Count(); i++)
    {
        @Html.Hidden("Tags[" + i + "]", tagArray[i])
    }
}

这会输出这个:

<input id="Tags_0_" name="Tags[0]" type="hidden" value="21111111" />
etc

我在 SO 上看到了各种问题,说您可以使用模型绑定器可以理解的特定格式的数组(如上)用于绑定列表 - 例如:

Creating HiddenFor IEnumerable<String> in View

但是,当页面出现错误并且我使用调试器查看帖子上绑定了什么时,虽然 model.tags 似乎有 3 个元素 - 它们都是空的。

我也试过这个:

@Html.Hidden("Tags[" + i + "].TagNo", tagArray[i])

但发布后 Customer.Tags 集合为空。

我做错了什么?如何在页面中隐藏此标签列表以便模型绑定器看到它?

【问题讨论】:

  • 使用强类型帮助器 - @Html.Hidden(m =&gt; m[i].Tags.TagNo)CreatedDate 同上),以便生成正确的 html。但是你为什么要这样做——如果你需要的话,只需在 POST 方法中再次获取集合。生成所有额外的 html 并将其发送给客户端,然后再将其原封不动地发送回去只会降低性能。注意Tags 属性必须是IList&lt;Tag&gt;
  • Thx - 我这样做是为了如果有模型错误我不必再次访问数据库来获取列表?!我错过了什么明显的东西吗?
  • 如果您设置了客户端验证,那么您很少需要点击返回视图。再次从数据库中获取它

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-5


【解决方案1】:

您的模型属性是 IEnumerable&lt;Tag&gt;,但下面的行发布 int[]

你需要改变

@{
    int[] tagArray = Model.Tags.Select(x => x.TagNo).ToArray();

    for (int i = 0; i < Model.Tags.Count(); i++)
    {
        @Html.Hidden("Tags[" + i + "]", tagArray[i])
    }
}

@for (int i = 0; i < @Model.Tags.Count; i++)
{
   <input id="Tags_@(i)__TagNo" name="Tags[@i].TagNo" type="hidden" value="@Model.Tags[i].TagNo" />
}

我建议在这种情况下使用编辑器模板

\Views\Shared\EditorTemplates\Tag.cs​​html:

@model mvcTest.Models.Tag
@Html.HiddenFor(a => a.TagNo)

父视图:

@for (int i = 0; i < @Model.Tags.Count; i++)
{
    @Html.EditorFor(a => a.Tags[i])
}

【讨论】:

  • 当您使用 EditorTemplate 时,它只是 @Html.EditorFor(a =&gt; a.Tags) - 不需要循环 - 该方法接受 IEnumerable&lt;T&gt; 并为集合中的每个项目呈现正确的 html。
猜你喜欢
  • 2022-01-14
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 2015-06-26
相关资源
最近更新 更多