DropdownListFor未在渲染的html中选择的选定值

时间:2012-05-18 15:13:32

标签: c# asp.net-mvc asp.net-mvc-3

我有一个扩展方法,我正在尝试使用枚举属性来创建下拉列表,并设置所选项目:

public enum DefaultEnumSelectItemOptions
{
    AddDefaultItemIfEnumIsZero,
    ZeroEnumIsDefaultItem
}
public static SelectList ToSelectList(this object enumObj, DefaultEnumSelectItemOptions option = DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
{
    var asEnum = Enum.Parse(enumObj.GetType(), enumObj.ToString());
    var values = Enum.GetValues(enumObj.GetType());
    var dataItems = new List<Tuple<string, int>>();
    dataItems.Add(new Tuple<string, int>("Select One", -1));
    for (int i = 0; i < values.Length; i++)
    {
        int enumValue = (int)values.GetValue(i);
        if (enumValue == 0)
        {
            if (option != DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
            {
                dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
            }
        }
        else
        {
            dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
        }
    }
    var selectedItemValue = (int)enumObj;
    if (selectedItemValue == 0 && option == DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
    {
        selectedItemValue = -1;
    }
    return new SelectList(dataItems, "Item2", "Item1", selectedItemValue);
}

模型如下所示:

public enum PropertyTypes
{
    Unknown=0,
    Vehicle,
    Other
}

[DataContract]
public class Property : ClaimEntity
{
    [DataMember]
    public PropertyTypes PropertyType { get; set; }

    public Property()
    {
        this.PropertyType = PropertyTypes.Vehicle;
    }
}

最后,视图如下所示:

@Html.DropDownListFor(m => m.PropertyType, Model.PropertyType.ToSelectList())

当我在扩展方法中设置断点时,它似乎是正确的,但所选的选项没有出现在html中。

dropdown issue

我做错了什么?

修改我将其更改为按照建议使用SelectListItem,但我仍然没有看到值选择:

enter image description here

2 个答案:

答案 0 :(得分:7)

我实际上遇到了这个问题,并发现DropDownListFor(和DropDownList)助手对自己的好处有点过于聪明。

即使您传递了一组SelectListItem并且其中一个Selected = true,帮助者实际上会评估您的模型,对其执行Convert.ToString() ,并尝试匹配该值。如果找不到值,它将不会选择任何内容。

我个人认为这是MVC中的一个重大错误,他们似乎没有在MVC4中纠正。假设对象的ToString()方法与下拉列表中的值(而不是显示文本)匹配,这是一个完全虚假的假设。

编辑:关于修复此问题的方法......

  1. 更改ToString()方法以返回值,并找出另一种获取显示文字的方式。
  2. 由于您使用的是枚举,因此您可以只使用值和显示文本的字符串版本。它仍然可以很好地绑定。
  3. 构建您自己的下拉列表

答案 1 :(得分:0)

我已经使用这种方法来创建我的下拉列表,如果有人感兴趣,它可以工作,但可能不是一个聪明的方法,因为我是MVC的新手。你需要检查firstelement是否其枚举值对应于任何有效的枚举并将其推入选择列表方法重载但是我很急,所以不这样做。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

    public static class Extensions
    {
        public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
        {
            var typeOfProperty = modelExpression.ReturnType;
            if (!typeOfProperty.IsEnum)
            {
                throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));
            }

            Dictionary<int, string> KeyValuePair = new Dictionary<int, string>();
            Array EnumValues = Enum.GetValues(typeOfProperty);
            foreach (var item in EnumValues)
            {
                KeyValuePair.Add((int)item, item.ToString());
            }

            var selectList = new SelectList(KeyValuePair, "Key", "Value");
            return htmlHelper.DropDownListFor(modelExpression, selectList, firstElement);
        }
    }

并在我的页面中将其用作

Html.EnumDropDownListFor(m => m.AccountType, ContextConstants.defaultSelectionString)