看来这个问题被问了太多次了.但是,这让我发疯.
这是我的(简化)模型.
public class UserEditModel
{
[Required]
public string Title { get; set; }
private IEnumerable<SelectListItem> _titleList;
public IEnumerable<SelectListItem> TitleList
{
get { return _titleList.Select(x => new SelectListItem {
Selected = (x.Value == Title),
Text = x.Text,
Value = x.Value
});
}
set { _titleList = value; }
}
}
TitleList成员中每个SelectListItem的Text和Value属性是相同的.例如:
new SelectListItem { Text = "Mr", Value = "Mr" }
发布以下代码后,将正确的Title值绑定到模型,但是每当响应POST或GET将模型推到视图时,即使所有智能感知都不会在下拉列表中设置所选值表明存在正确的值.
@Html.DropDownListFor(x => x.Title, Model.TitleList)
我已经根据几篇文章和几则SO答案确保代码正确无误,所以我很困惑.
有什么建议么?
更新:
为了完整起见,这是操作和支持方法:
[HttpGet]
public ActionResult Edit(int id)
{
var user = _userService.Get(id);
var model = new UserEditModel()
{
...
Title = user.Title,
TitleList = ListTitles()
};
return View(model);
}
private IEnumerable<SelectListItem> ListTitles()
{
var items = new[] {
new SelectListItem() {Text = "Mr", Value = "Mr" },
new SelectListItem() {Text = "Mrs", Value = "Mrs"},
new SelectListItem() {Text = "Ms", Value = "Ms"},
new SelectListItem() {Text = "Miss", Value = "Miss"},
new SelectListItem() {Text = "Professor", Value = "Professor"},
new SelectListItem() {Text = "Dr", Value = "Dr" }
};
return items;
}
如您所见,没有什么花哨的东西,只是一个简单的实现.
解决方法:
您需要添加ModelState.Clear(),因为默认情况下从后操作返回视图时,它认为该视图验证失败,因此使用ModelState中的值而不是Model中的值.许多人认为这实际上是MVC中的错误,但这是设计使然:
ASP.NET MVC assumes that if you’re rendering a View in response to a
HttpPost
, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check inModelState
for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed.