您使用的方法是正确的。我同意你总是使用视图模型而不是 ViewBag。
在您的视图模型中,您应该将字典更改为 MultiSelectList,以便您也可以拥有选定的值。
public IList<int> PriorInsuranceCompaniesSelected { get; set; }
public MultiSelectList PriorInsuranceCompanies { get; set; }
然后,如果已经选择了一些 Id(例如从存储库加载数据时获得的信息),则映射第一个字段,然后映射所有值的第二个字段。
从 Get 部分的控制器中(仅以一些代码为例):
model.PriorInsuranceCompaniesSelected = new List<int>();
var companies = repository.GetPriorInsuranceCompanies();
//add to your PriorInsuranceCompaniesSelected the values already checked from your entity
var entity = repository.GetEntityBy(id);
if (entity.PriorInsuranceCompanies != null)
foreach (var item in entity.PriorInsuranceCompanies)
model.PriorInsuranceCompaniesSelected.Add(item.Id);
var select = (from s in companies select new { Id = s.Id, Name = s.Name }).OrderBy(x => x.Name); //.ToList;
model.PriorInsuranceCompanies = new MultiSelectList(select, "Id", "Name", model.PriorInsuranceCompaniesSelected);
然后在您的 Html 中,您将有这样的输出
@foreach (var item in Model.PriorInsuranceCompanies)
{
<label for="@item.Value" class="check">
<input type="checkbox" id="@item.Value" name="PriorInsuranceCompaniesSelected" value="@item.Value" @(item.Selected ? "checked" : "") />@item.Text</label>
}
在发布时,ModelBinder 会自动将正确的对象映射到您的模型。您只需检查 model.PriorInsuranceCompaniesSelected 中的值
[HttpPost]
public ActionResult MyForm(MyViewModel model)
{
if (ModelState.IsValid)
{
try
{
//your mapping code or whatever...
//You do your things with the selected ids..
if (model.PriorInsuranceCompaniesSelected != null && model.PriorInsuranceCompaniesSelected.Count > 0)
entity.PriorInsuranceCompanies = repository.GetCompaniesBy(model.PriorInsuranceCompaniesSelected);
else
entity.PriorInsuranceCompanies = new List<Comapny>();
repository.Save(entity);
return RedirectToAction("Index");
}
catch (RulesException ex)
{
ex.CopyTo(ModelState);
}
catch
{
ModelState.AddModelError("", "My generic error taken form a resource");
}
}
//rehydratates the list in case of errors
//....
return View(model);
}
这应该让您知道该怎么做。我希望它有帮助