我有一个视图模型,用于将字段组合成字段集的页面。
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");
}
答案 0 :(得分:0)
发布表单时,只会发布AvailableFields和UsedFields的ID。如果您有多个值,那么您将获得逗号分隔的ID列表,因此modelbinding将无法将这些已发布的ID绑定到FieldsetVM postedVm
。
如果您执行public ActionResult Create(int[] availableFields, int[] usedFields)
之类的操作,您应该能够获得所选的ID。