未在MVC4中的DropDownListFor()上设置选定的值

时间:2013-04-17 08:10:52

标签: c# asp.net-mvc asp.net-mvc-4 razor drop-down-menu

似乎这个问题已被问过太多次了。但这让我疯了。

这是我的(简化)模型。

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; }
    }
}

Text成员中每个Value的{​​{1}}和SelectListItem属性相同。例如:

TitleList

发布以下代码时,正确的new SelectListItem { Text = "Mr", Value = "Mr" } 值绑定到模型,但只要模型被推送到视图以响应POST或GET,就不会在下拉列表,即使所有intellisense都显示正确的值存在。

Title

我根据几篇文章和几个SO答案确保代码是正确的,所以我很难过。

有什么建议吗?

更新

为了完整性,这是行动和支持方法:

@Html.DropDownListFor(x => x.Title, Model.TitleList)

如你所见,没有什么特别的,只是一个简单的实施。

3 个答案:

答案 0 :(得分:2)

您需要添加ModelState.Clear(),因为默认情况下,当从帖子操作返回视图时,它认为验证失败,因此使用ModelState中的值模型中的值。许多人认为这实际上是MVC中的一个 bug ,但它的设计是:

  

ASP.NET MVC假设如果您在回复HttpPost时呈现View,并且您正在使用Html Helpers,那么您最有可能重新显示验证失败的表单。因此,Html Helpers实际上会在ModelState中检查要在模型中查看之前在字段中显示的值。这使他们能够重新显示用户输入的错误数据,并在需要时显示匹配的错误消息。

Link

答案 1 :(得分:2)

嗯,似乎代码实际上没有任何问题,只是模型中Title属性的名称。

看起来Title是一个保留字并将其替换为TitleX或更恰当地Salutation,这使得一切正常。

答案 2 :(得分:0)

您确定在控制器中正确检索了选择列表项吗? 对我来说它工作正常。 我会使用get方法而不是属性(GetTitleList(string value)),以避免在代码中进一步获取选择列表时出错。