forms - ModelState 在发布后覆盖 MultiSelectList 值

标签 forms validation asp.net-mvc-4 multi-select modelstate

遇到一个奇怪的问题。

在包含 MultiSelectList 的表单的 POST 操作期间,我可以看到所有选定的值...到目前为止一切顺利。 但是,如果由于其他字段的某些验证错误而需要重新显示表单,则 MultiSelectList Dropdown 字段仅显示第一个选定的值,而不是第一个请求期间选择的所有值...

当我在返回 View 之前调用 ModelState.Clear() 时,我可以从数据库重建多选值列表,并且所有选定值都会显示......但这种行为并不是 100% 我想要的。

我只想重用从发布请求中获得的选定 ID,但不知何故,这些值被模型状态覆盖,只显示第一个选定值。

这里有一些代码:

[HttpPost]
public ActionResult Employer(EmployerViewModel model)
{
...
model.IndustrialSectorsMultiSelectList = new MultiSelectList(industrialSectors, "Id", "Name", model.IndustrialSectorsSelectedIds);
...
return View(model);
}

当我调试代码时,我可以看到 model.InduscialSectorsSelectedIds 包含所有选定的值...但在 View 中突然只显示第一个值。

有人来帮忙吗? :-)

先谢谢了!!! 西蒙

更新

抱歉,如果我不够清楚。我不使用 ModelState.Clear()。这只是我试图找出正在发生的事情以及为什么即使我手动设置的值在 Post 期间也没有被采用而它们在 Get 期间正常工作的原因之一。它帮助我发现它实际上是 ModelState 以仅显示第一个选定值的方式覆盖我发布的值。

似乎所选值作为逗号分隔的字符串“12,18,33,47”传递。当我在 HttpPost 操作期间重新创建 View 时,它只需要“12”并忽略列表的其余部分。

这里有更多代码:

View 模型:

public MultiSelectList IndustrialSectorsMultiSelectList { get; set; }
public int[] IndustrialSectorsSelectedIds { get; set; }

采取行动:

EmployerViewModel model = new EmployerViewModel();
Employer employer = ServiceManager.EmployerService.GetEmployerByUser(AppUser);
...
var industrialSectors = ServiceManager.DefaultValuesService.GetIndustrialSectors();
model.IndustrialSectorsMultiSelectList = new MultiSelectList(industrialSectors, "Id", "Name", employer.IndustrialSectors.Select(item => item.Id).ToList());

当我需要重新显示 View 时发布操作:

var industrialSectors = ServiceManager.DefaultValuesService.GetIndustrialSectors();
model.IndustrialSectorsMultiSelectList = new MultiSelectList(industrialSectors, "Id", "Name", model.IndustrialSectorsSelectedIds);

查看:

@Html.DropDownListFor(m => m.IndustrialSectorsSelectedIds, Model.IndustrialSectorsMultiSelectList, new { @class = "select_branche form-control", @multiple = "multiple" })

如上所述...在 GET 期间,所选值正确显示在 View 中。 在发布期间,即使在发布操作期间所有选定的值都在我的 int[] 中,也仅采用模型中的第一个选定值。所以我传递给新的 MultiSelectList 的 int[] 没问题。 只是为了测试,我尝试在发布期间使用与获取操作中完全相同的代码构建 View ...在获取期间我看到所有值...在发布期间仅显示第一个值。

不知道该怎么办:-(

更新2

当我将以下行添加到我的后操作方法中时,我设法修复了此行为。从 ModelState 中删除 int[] 并在我的 ViewModel 中设置 int[] = null。

var industrialSectors = ServiceManager.DefaultValuesService.GetIndustrialSectors();
model.IndustrialSectorsMultiSelectList = new MultiSelectList(industrialSectors, "Id", "Name", model.IndustrialSectorsSelectedIds);
//Fix issue that modelstate value only sets the first selected value
ModelState.Remove("IndustrialSectorsSelectedIds");
model.IndustrialSectorsSelectedIds = null;

但我仍然不知道为什么它会这样。这是某种错误吗? 任何评论都会很棒。谢谢!!

最佳答案

对不起,也许我太笨了......

当我的 View 中将 DropDownListFor 更改为 ListBoxFor 时,一切都按预期工作。 :-)

关于forms - ModelState 在发布后覆盖 MultiSelectList 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32832875/

相关文章:

Javascript 表单验证不起作用

asp.net-mvc - ASP.NET MVC 4,如何在将 View 模型对象用作操作方法参数之前访问/修改 View 模型对象(并更改 View 和操作方法)?

javascript - 在不可绑定(bind)元素内使用 Angular 数据绑定(bind)和指令

javascript - 如何在 jQuery 中验证表单中的空输入框

javascript - PHP 无法使用 Jquery 表单中的提交按钮

php - 验证我的 PHP 表单并提交到数据库

c# - WPF DataGrid 验证错误?

c - 为什么 scanf llu 不验证 %llu?

asp.net-mvc - Html.BeginForm() 和 ajax.beginform() 之间的区别

asp.net-mvc-4 - 带有返回 URL (OAuth) 的注销链接