MVC ViewModel中的ICollection <selectlistitem> </selectlistitem>

时间:2014-03-26 21:10:19

标签: c# asp.net-mvc asp.net-mvc-viewmodel

我有一个视图模型,用于将字段组合成字段集的页面。

VM看起来像这样:

public class FieldsetVM
{
    public Int64 ID { get; set; }
    public string Name { get; set; }

    [Display(Name = "Available Fields")]
    public ICollection<SelectListItem> AvailableFields { get; set; }

    [Display(Name = "Current Fields")]
    public ICollection<SelectListItem> UsedFields { get; set; }

    public FieldsetVM(int id, string name, List<Field> availFields, List<Field> usedFields)
    {
        this.ID = id;
        this.Name = name;

        this.AvailableFields = new List<SelectListItem>();

        foreach (Field field in availFields)
            this.AvailableFields.Add(new SelectListItem { Text = string.Format("{0} ({1})", field.Name, field.FieldType.ToString()), Value = field.FieldID.ToString() });

        this.UsedFields = new List<SelectListItem>();

        foreach (Field field in usedFields)
            this.UsedFields.Add(new SelectListItem { Text = string.Format("{0} ({1})", field.Name, field.FieldType.ToString()), Value = field.FieldID.ToString() });
    }

    public FieldsetVM()
    {
    }
}

进入控制器看起来像这样:

    [HttpGet]
    public ActionResult Create()
    {
        FieldsetVM vm = new FieldsetVM(0, "", uw.FieldRepo.Get().ToList(), new List<Field>());

        return View(vm);
    }

视图的相关部分如下所示:

    <div class="col-md-3 col-xs-6">
    <div class="editor-label">
        @Html.LabelFor(m => m.AvailableFields)
    </div>
    <div class="editor-field">
        @Html.ListBoxFor(m => m.AvailableFields, Model.AvailableFields)
    </div>

    <button type="button" onclick="moveSelected('AvailableFields','UsedFields');">Move Selected</button>
</div>

<div class="col-md-3 col-xs-6">
    <div class="editor-label">
        @Html.LabelFor(m => m.UsedFields)
    </div>
    <div class="editor-field">
        @Html.ListBoxFor(m => m.UsedFields, Model.UsedFields)
    </div>

    <button type="button" onclick="moveSelected('UsedFields','AvailableFields');">Remove Selected</button>
</div>

一小部分JavaScript连接两个列表框:

function moveSelected(firstSelectId, secondSelectId) {
$('#' + firstSelectId + ' option:selected').appendTo('#' + secondSelectId);
$('#' + firstSelectId + ' option:selected').remove();

}

然后我在控制器中有一个POST:

    [HttpPost]
    public ActionResult Create(FieldsetVM postedVm)
    {
        Fieldset fs = new Fieldset();

        fs.Name = postedVm.Name;

        if (fs.Fields == null)
            fs.Fields = new List<Field>();

        fs.Fields.Clear();

        foreach (SelectListItem item in postedVm.UsedFields)
            fs.Fields.Add(uw.FieldRepo.GetByID(item.Value));

        uw.FieldsetRepo.Insert(fs);

        return RedirectToAction("Index");
    }

我的期望是,在postedVm中,我们将能够看到用户在UsedFields中选择的值。相反,当用户回发到HttpPost Create()操作时,UsedFields和AvailableFields总是空白。

我正在试图找出原因:肯定在列表框之间移动项目是一种相当常见的配置方式吗? MVC不应该查看生成的值并使用它们来填充postedVm对象吗?

编辑根据最佳答案的反馈,这是我修改后的创建/发布操作。

        [HttpPost]
    public ActionResult Create(FieldsetVM postedVm, int[] UsedFields)
    {
        Fieldset fs = new Fieldset();

        fs.Name = postedVm.Name;

        fs.Fields = new List<Field>();

        foreach (int id in UsedFields)
            fs.Fields.Add(uw.FieldRepo.GetByID(id));

        uw.FieldsetRepo.Insert(fs);
        uw.Save();

        return RedirectToAction("Index");
    }

1 个答案:

答案 0 :(得分:0)

发布表单时,只会发布AvailableFields和UsedFields的ID。如果您有多个值,那么您将获得逗号分隔的ID列表,因此modelbinding将无法将这些已发布的ID绑定到FieldsetVM postedVm

如果您执行public ActionResult Create(int[] availableFields, int[] usedFields)之类的操作,您应该能够获得所选的ID。