从MVC 5.1 EnumDropDownListFor中排除/删除值

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

枚举:

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

视图:

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

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

谢谢!

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

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

修改自@ dav_i的答案。

这并不完美,但它正是我所使用的。 以下是HtmlHelper的扩展。 扩展方法看起来像ASP.NET中的EnumDropDownListFor ,如果有任何应用于Enum值,则使用DisplayAttribute

 ///  /// Returns an HTML select element for each value in the enumeration that is /// represented by the specified expression and predicate. ///  /// The type of the model. /// The type of the value. /// The HTML helper instance that this method extends. /// An expression that identifies the object that contains the properties to display. /// The text for a default empty item. This parameter can be null. /// A  to filter the items in the enums. /// An object that contains the HTML attributes to set for the element. /// An HTML select element for each value in the enumeration that is represented by the expression and the predicate. /// If expression is null. /// If TEnum is not Enum Type. public static MvcHtmlString EnumDropDownListFor(this HtmlHelper htmlHelper, Expression> expression, Func predicate, string optionLabel, object htmlAttributes) where TEnum : struct, IConvertible { if (expression == null) { throw new ArgumentNullException("expression"); } if (!typeof(TEnum).IsEnum) { throw new ArgumentException("TEnum"); } ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); IList selectList = Enum.GetValues(typeof(TEnum)) .Cast() .Where(e => predicate(e)) .Select(e => new SelectListItem { Value = Convert.ToUInt64(e).ToString(), Text = ((Enum)(object)e).GetDisplayName(), }).ToList(); if (!string.IsNullOrEmpty(optionLabel)) { selectList.Insert(0, new SelectListItem { Text = optionLabel, }); } return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes); } ///  /// Gets the name in  of the Enum. ///  /// A  that the method is extended to. /// A name string in the  of the Enum. public static string GetDisplayName(this Enum enumeration) { Type enumType = enumeration.GetType(); string enumName = Enum.GetName(enumType, enumeration); string displayName = enumName; try { MemberInfo member = enumType.GetMember(enumName)[0]; object[] attributes = member.GetCustomAttributes(typeof(DisplayAttribute), false); DisplayAttribute attribute = (DisplayAttribute)attributes[0]; displayName = attribute.Name; if (attribute.ResourceType != null) { displayName = attribute.GetName(); } } catch { } return displayName; } 

例如:

 @Html.EnumDropDownListFor( model => model.UserStatus, (userStatus) => { return userStatus != UserStatus.Active; }, null, htmlAttributes: new { @class = "form-control" }); 

这将创建一个没有Active选项的Enum下拉列表。

您可以通过循环枚举中的值来自己创建下拉列表,如果它不是Pending,则只包括

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

  

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

  ///  /// ///  /// The type of the model. /// The type of the value. /// The HTML helper instance that this method extends. /// An expression that identifies the object that contains the properties to display /// The unselected item initial value ///  ///  public static MvcHtmlString SortedEnumDropDownListFor(this HtmlHelper htmlHelper, Expression> expression, string initalValue, object htmlAttributes = null) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = GetNonNullableModelType(metadata); Type baseEnumType = Enum.GetUnderlyingType(enumType); List items = new List(); 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()) { text = displayAttribute.GetName(); } items.Add(new SelectListItem { Text = text, Value = value, Selected = selected }); } items = new List(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(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes = null) { MvcHtmlString helper = SortedEnumDropDownListFor(htmlHelper, expression, string.Empty, htmlAttributes); return helper; } 

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