从MVC 5.1 EnumDropDownListFor中排除/删除值

时间:2014-11-25 17:28:21

标签: c# asp.net-mvc razor enums html-helper

我有一个用于用户管理页面的枚举列表。我正在使用MVC 5.1中的新HtmlHelper,它允许我为Enum值创建一个下拉列表。我现在需要从列表中删除Pending值,这个值只能以编程方式设置,不应该由用户设置。

枚举:

public enum UserStatus
{
    Pending = 0,
    Limited = 1,
    Active = 2
}

查看:

@Html.EnumDropDownListFor(model => model.Status)

无论如何,要么覆盖当前控件,要么编写一个允许我指定枚举的自定义HtmlHelper,或者从结果列表中排除枚举?或者你会建议我用jQuery做客户端的东西,一旦生成就从下拉列表中删除值?

谢谢!

4 个答案:

答案 0 :(得分:38)

您可以构建一个下拉列表:

@{ // you can put the following in a back-end method and pass through ViewBag
   var selectList = Enum.GetValues(typeof(UserStatus))
                        .Cast<UserStatus>()
                        .Where(e => e != UserStatus.Pending)
                        .Select(e => new SelectListItem 
                            { 
                                Value = ((int)e).ToString(),
                                Text = e.ToString()
                            });
}
@Html.DropDownListFor(m => m.Status, selectList)

答案 1 :(得分:5)

您可以looping through the values in the enum自行创建下拉菜单,只有<option>才会包含

以下是它应该如何工作,但正如您所看到的,我不确定您将使用哪个选项标记的值或文本。

<select>
foreach (var status in Enum.GetValues(typeof(UserStatus)))
{
    if(status != UserStatus.Pending)
    {
        <option value="status.???">@status.???</option>
    }
}
</select>

答案 2 :(得分:0)

以下是HtmlHelper的扩展。它与ASP.NET中的EnumDropDownListFor扩展非常相似,但它按项目显示名称对SelectListItem进行排序。它有一个暗示名称:SortedEnumDropDownListFor,用于不与原始扩展名冲突。

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TEnum">The type of the value.</typeparam>
    /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    /// <param name="expression">An expression that identifies the object that contains the properties to display</param>
    /// <param name="initalValue">The unselected item initial value</param>
    /// <param name="htmlAttributes"></param>
    /// <returns></returns>
    public static MvcHtmlString SortedEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string initalValue, object htmlAttributes = null)
    {

        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        Type enumType = GetNonNullableModelType(metadata);
        Type baseEnumType = Enum.GetUnderlyingType(enumType);
        List<SelectListItem> items = new List<SelectListItem>();

        foreach (FieldInfo field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
        {
            string text = field.Name;
            string value = Convert.ChangeType(field.GetValue(null), baseEnumType).ToString();
            bool selected = field.GetValue(null).Equals(metadata.Model);

            foreach (DisplayAttribute displayAttribute in field.GetCustomAttributes(true).OfType<DisplayAttribute>())
            {
                text = displayAttribute.GetName();
            }

            items.Add(new SelectListItem
            {
                Text = text,
                Value = value,
                Selected = selected
            });
        }

        items = new List<SelectListItem>(items.OrderBy(s => s.Text));
        items.Insert(0, new SelectListItem { Text = initalValue, Value = "" });

        return htmlHelper.DropDownListFor(expression, items, htmlAttributes);

    }        

    private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
    {
        Type realModelType = modelMetadata.ModelType;
        Type underlyingType = Nullable.GetUnderlyingType(realModelType);

        if (underlyingType != null)
        {
            realModelType = underlyingType;
        }

        return realModelType;
    }

如果您不想打扰未选择的项目intitia,只需构建一个像这样的重载:

public static MvcHtmlString SortedEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes = null)
        {
            MvcHtmlString helper = SortedEnumDropDownListFor(htmlHelper, expression, string.Empty, htmlAttributes);
            return helper;
        }

你很高兴。我希望它有所帮助。

答案 3 :(得分:0)

我一直在寻找这个问题的答案,因为它与.NET Core MVC有关。给定以下代码,您可以限制不想在UI中显示的枚举:

<select asp-for="UserStatus" asp-items="@(Html.GetEnumSelectList<UserStatus>().Where(x => x.Value != 0))" class="form-control">
    <option selected="selected" value="">Please select</option>
</select>

希望其他人都可以找到此答案。