使用Ajax.BeginForm(MVC 4)发布包含对象列表的ViewModel

时间:2015-04-08 00:46:20

标签: c# ajax asp.net-mvc wpf asp.net-mvc-4

视图成功地将控制器传递给SidebarViewModel对象,但Filters数据成员为null。所以绑定在某个地方失败了。

经过一些阅读后,我觉得FilterViewModel列表没有绑定,因为绑定器无法推断出Filters [0] .Value是一个FilterViewModel,因为该视图模型的其他数据成员都不存在。但是将剩余的数据成员添加为隐藏字段并没有解决问题。

知道为什么FilterViewModel列表没有绑定吗?

的ViewModels

public class SidebarViewModel
{
    public List<FilterViewModel> Filters;
}

public class FilterViewModel
{
    public string DisplayName { get; internal set; }
    public string EditorTemplate { get; internal set; }
    public string Value { get; set; }
    public bool Visible { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

查看

@model SidebarViewModel
@using (Ajax.BeginForm("Filter", "Controller", Model, new AjaxOptions
{
    UpdateTargetId = "tool-wrapper",
    LoadingElementId = "loading-image",
    HttpMethod = "POST"
}))
{
    <fieldset>
        @foreach (var filter in Model.Filters.Where(x => x.Visible).Select((value, i) => new {i, value}))
        {
            <div class="control-group">
                @Html.DisplayFor(m => m.Filters[filter.i].DisplayName)
                @Html.EditorFor(m => m.Filters[filter.i], "Template")
            </div>
        }

        <button type="submit">Filter</button>
    </fieldset>
}

编辑模板

@model FilterViewModel
@Html.DropDownListFor(m => m.Value, Model.Items, "(Select)")

生成的HTML表单

<select id="Filters_0__Value" name="Filters[0].Value">
    <option value="">(Select)</option>
    // More options
</select>

<select id="Filters_1__Value" name="Filters[1].Value">
    <option value="">(Select)</option>
    // More options
</select>

控制器

[HttpPost]
public ActionResult Filter(SidebarViewModel sidebar)
{
    // Stuff.
}

1 个答案:

答案 0 :(得分:1)

Filters是字段,而不是属性,因此您需要添加getter和setter,以便DefaultModelBinder可以设置值。

public class SidebarViewModel
{
    public List<FilterViewModel> Filters { get; set; }
}

但是,由于您的代码不能为您提供正确的模型绑定,因此您还有其他一些问题。您需要将EditorTemplate重命名为/Views/Shared/EditorTemplates/FilterViewModel.cshtml,然后在主视图中使用(不foreach循环)

@Html.EditorFor(m => m)

EditorFor()方法将使用正确的名称属性(包括索引器)正确生成每个项目的控件。另请注意,在将集合传递给视图之前,应先过滤控制器中的集合。