c# - MVC3 EnumDropdownList 选定值

标签 c# asp.net-mvc-3

有一些有用的扩展方法可以在下拉列表中使用显示枚举。例如herehere .

但是我遇到了一个问题,那就是如果枚举用 Description 属性修饰,这些帮助器将不起作用。第一个示例与“描述”属性完美配合,但它没有设置选定的值。第二个示例设置选定的值,但不使用描述属性。因此,我需要将这两种方法组合成一个可以正确执行这两种方法的工作助手。我有很多变体来让它工作,但到目前为止还没有成功。我尝试了多种方法来创建选择列表,但不知何故它忽略了 Selected 属性。在我的所有测试中,一项的 Selected 属性被设置为 true,但该属性被忽略。 因此,任何想法都非常受欢迎!

这是我尝试过的最新代码:

public static IEnumerable<SelectListItem> ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
            var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
            var listItem = new SelectListItem
            {
                Value = ((int)item).ToString(),
                Text = title,
                Selected = selectedItem == item.ToString()
            };

            items.Add(listItem);
        }
        return items;

    }

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

        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : modelExpression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownListFor(modelExpression, ToSelectList(modelExpression.ReturnType, value.ToString()));
    }

最佳答案

我对枚举也有同样的问题,它实际上设置了自定义值

public enum Occupation
{
    [Description("Lorry driver")] LorryDriver = 10,
    [Description("The big boss")] Director = 11,
    [Description("Assistant manager")] AssistantManager = 12
}

我发现,当我使用 DropDownListFor() 时,它不会使用 SelectListItem 集合中的所选项目来设置所选选项。相反,它选择一个选项,其值等于我尝试绑定(bind)到的属性(m => m.Occupation),为此它使用枚举的 .ToString() 而不是枚举的实际整数值。所以我最终的结果是设置 SelectListItem 的值,如下所示:

var listItem = new SelectListItem
{
    Value = item.ToString(), // use item.ToString() instead
    Text = title,
    Selected = selectedItem == item.ToString() // <- no need for this
};

辅助方法:

public static class SelectListItemsForHelper
{
    public static IEnumerable<SelectListItem> SelectListItemsFor<T>(T selected) where T : struct
    {
        Type t = typeof(T);
        if (t.IsEnum)
        {
            return Enum.GetValues(t).Cast<Enum>().Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
        }
        return null;
    }

    public static string GetDescription<TEnum>(this TEnum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());

        if (fi != null)
        {
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
                return attributes[0].Description;
        }

        return value.ToString();
    }
}

在 View 中:

@Html.DropDownListFor(m => m.Occupation, SelectListItemsForHelper.SelectListItemsFor(Model.Occupation), String.Empty)

关于c# - MVC3 EnumDropdownList 选定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9280465/

相关文章:

javascript - 想要使用 Ajax 加载下拉列表中所选选项的图像和一些文本

asp.net-mvc - httpErrors errorMode = "Detailed"仅适用于特定错误代码

asp.net-mvc-3 - 是否可以将部分 View 传递给与其所在 View 使用的模型不同的模型?

c# - 确保 _Layout.cshtml 的 View 模型数据的最优雅方式

c# - 如何使用taglib-sharp?

c# - 如何使用响应式扩展实现 'handle remaining' 观察者

c# - 如何从 Dapper 查询而不是 default(T) 返回 null?

jquery - Ajax 文件上传在 IE7 中不起作用

c# - “Strange” C#属性语法

c# - 为 URI 关联注册应用程序 (Windows Phone 8.1 RT)