在ASP.net MVC中从Enum下拉列表中选择的项目

时间:2010-06-13 15:25:17

标签: c# asp.net-mvc

很抱歉,如果这是一个复制品,我的搜索结果一无所获。

我使用以下方法为枚举类型生成下拉列表(从此处解除:http://addinit.com/?q=node/54):

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected)
{
    if (!type.IsEnum)
        throw new ArgumentException("Type is not an enum.");

    if(selected != null && selected.GetType() != type)
        throw new ArgumentException("Selected object is not " + type.ToString());

    var enums = new List<SelectListItem>();
    foreach (int value in Enum.GetValues(type))
    {
        var item = new SelectListItem();
        item.Value = value.ToString();
        item.Text = Enum.GetName(type, value);

        if(selected != null)
            item.Selected = (int)selected == value;

        enums.Add(item);
     }

    return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, enums, "--Select--");
}

除了一件事,它工作正常。如果我给下拉列表提供与我的模型上的属性相同的名称,则未正确设置所选值。这意味着:

<%= Html.DropDownList("fam", typeof(EnumFamily), Model.Family)%>

但这不是:

<%= Html.DropDownList("family", typeof(EnumFamily), Model.Family)%>

因为我试图将整个对象直接传递给我发布的控制器方法,所以真的喜欢在模型上为该属性命名的下拉列表。当使用“正确”名称时,下拉列表会正确发布,我似乎无法设置所选值。

我认为这不重要,但我在单声道2.6上运行MVC 1

编辑:我刚刚在Windows上对此进行了测试,我看到了相同的行为

3 个答案:

答案 0 :(得分:14)

尽量不要使用enum /的int值而不是:

item.Value = value.ToString();

使用:

item.Value = Enum.GetName(type, value);

imo正在发生的事情是它自动设置下拉列表的选定值以匹配模型 - 使用枚举名称而不是其int值。请记住,视图引擎不仅会在已发布的表单中查找已选择的值(在已经发布的情况下),而且还会在模型+ viewdata中传递给视图。只有当它没有找到它时,它才会使用你指定的选定值。

答案 1 :(得分:4)

实际上,这是解决方案。这个问题与我的解决方案相同。
ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model

    public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected)
    {
        if (!type.IsEnum)
            throw new ArgumentException("Type is not an enum.");

        if (selected != null && selected.GetType() != type)
            throw new ArgumentException("Selected object is not " + type.ToString());

        var enums = new List<SelectListItem>();
        foreach (int value in Enum.GetValues(type))
        {
            var item = new SelectListItem();
            item.Value = value.ToString();
            item.Text = Enum.GetName(type, value);

            if (selected != null)
                item.Selected = (int)selected == value;

            enums.Add(item);
        }

        // set ViewData first
        helper.ViewData[name] = enums;

        // pass in "null" intentionally into the DropDownList extension method
        return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, null, "--Select--");
    }

使用item.Value = Enum.GetName(type, value);下拉&lt;选项&gt;要呈现为枚举名称的值。 我个人更喜欢将int值作为回发。

希望它有所帮助。

答案 2 :(得分:0)

这似乎不太正确,但我发现如果我使用{nameOfInputParameter}。{propertyName}命名下拉列表,它会正确加载和发布。因此,如果有问题的表单发布到一个方法,该方法采用与名为“myModel”的表单模型相同类型的参数,则可以像这样设置系列的下拉列表:

<%= Html.DropDownList("myModel.family", typeof(EnumFamily), Model.Family)%>

使用myModel_family的id和myModel.family的名称呈现。我不确定如何感受到这一点,对我来说似乎有点不对劲。但到目前为止似乎确实有效。它确实引入了一个新问题。你不能再初始化文本框等......就像这样:

<%= Html.TextBox("name") %>

这将正确加载值,但是当您将“myModel”作为参数发布到控制器方法时,值不会被识别为正在提交的对象的一部分。所以我们需要在输入名称中包含参数名称。

但是,以下内容并未解析为某个值,至少使用默认的模型绑定器(我想知道是否会在这里挖掘出最佳答案):

<%= Html.TextBox("myModel.name") %>

所以你需要这样做:

<%= Html.TextBox("myModel.name", Model.Name) %>

这一切都变得非常严重(特别是在我需要能够处理模型为null的情况的页面上)。希望其他人有更好的主意:)