【问题标题】:ModelState overwrites MultiSelectList values after postModelState 在发布后覆盖 MultiSelectList 值
【发布时间】:2015-12-26 06:41:10
【问题描述】:

有一个奇怪的问题。

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

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

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

这里有一些代码:

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

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

有人来帮忙吗? :-)

提前致谢!!! 西蒙

更新

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

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

这里有更多代码:

视图模型:

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());

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

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 期间,所选值正确显示在视图中。 在 Post 期间,即使在 post 操作期间所有选定的值都在我的 int[] 中,也只会从模型中获取第一个选定的值。所以我传递给新的 MultiSelectList 的 int[] 很好。 只是为了测试,我尝试在 Post 期间使用与 Get 操作中完全相同的代码构建 View...在 Get 期间我看到所有值...在 post 期间只有第一个。

不知道怎么办:-(

更新 2

当我将以下行添加到我的 post 操作方法时,我设法修复了此行为。从 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;

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

【问题讨论】:

  • 如果你绑定到一个属性(它被忽略),那么在MultiSelectList构造函数中添加最后一个参数是没有意义的。显示您对该属性的看法。你为什么打电话给ModelState.Clear()?你在哪里做的?
  • 您能否在剃刀视图中显示代码以显示MultiSelectList
  • 感谢阅读 :-) 我更新了我的帖子希望对您有所帮助...
  • 在我的帖子中添加了另一个更新...如果有人可以评论这是一个错误,或者如果这是按这样的设计工作,那将是非常棒的。 :-)

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


【解决方案1】:

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

在我的视图中将 DropDownListFor 更改为 ListBoxFor 时,一切正常。 :-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多