在ASP.NET MVC Core中将枚举用作下拉列表


79

我试图在Razor视图中使用标记帮助器在ASP.NET MVC Core中创建一个带有枚举属性的下拉列表:

这是模型:

public class PersonalMember : Member
{
    [Required, Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Required, Display(Name = "Last Name")]
    public string LastName { get; set; }

    [EnumDataType(typeof(Gender))]
    public Gender GenderType { get; set; }
}

public enum Gender
{
    Male = 1,
    Female = 2
}

这是视图中表单的一部分:

<div class="form-group">
    <label asp-for="GenderType" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <select asp-for="GenderType" asp-items="Html.GetEnumSelectList<GenderType>()">
            <option selected="selected" value="">Please select</option>
        </select>
        <span asp-validation-for="GenderType" class="text-danger" />
    </div>
</div>

我遇到的问题是,之后Html.GetEnumSelectListGenderType无法识别和显示为错误。

有谁知道如何解决这个问题?


2
尝试将其指定为... @(Html.GetEnumSelectList <GenderType>())“
KD

Answers:


113

我认为您不小心使用GenderTypeGender。正确的语法是

<select asp-for="GenderType" asp-items="Html.GetEnumSelectList<Gender>()">
    <option selected="selected" value="">Please select</option>
</select>

8
这应该是答案,它使用了现代标记帮助器,并向您展示了如何实现GetEnumSelectList <Enum>()来构建列表项。
布莱恩·哈特曼

在.net核心中对我
有用的

65

GenderType是您的媒体资源名称,而不是Enum类型。GetEnumSelectList方法希望您为其提供枚举类型,而不是模型中的属性名称。

试试这个:

Html.GetEnumSelectList<Gender>()

可能需要将其标记为asp-for中的元数据,例如:Html.GetEnumSelectList <GenderType.Meta.Gender>()。.OP并未标记使用了哪个版本的MVC框架
Mikael Puusaari,

我已经尝试过Html.GetEnumSelectList <Gender>()和Html.GetEnumSelectList <枚举Gender>()-它们都显示为错误
David Sharpe

1
使用上面的示例时,您会遇到什么错误?一样吗 我认为您的第二个示例不是有效的语法
ADyson

8
在剃须刀中,您需要用()包围:@(Html.GetEnumSelectList <Gender>()); 因为剃刀将<>解释为html标签,否则
–dysdyes

@ADyson,你能看到这个吗?stackoverflow.com/questions/48094102/…–

26

您可以简单地使用Razor语法:

@Html.DropDownList("StudentGender", 
    Html.GetEnumSelectList<Gender>(),
    "Select Gender",new { @class = "form-control" })

1
这确实是我们所需要的!
juF18年


6

以下是对我有用的。这是必要的,也是这样,因为枚举本身是在您用作模型的类的范围内声明的类。

<select asp-for="Status" class="form-control" asp-items="@Html.GetEnumSelectList<Cart.CartStatus>()"></select>

在我的模型下面(正在进行的工作)以供参考

 public class Cart
    {
        public int CartId { get; set; }
        public List<Order> Orders { get; set; }
        [Required]
        public string UserId { get; set; }
        public DateTime DeliveryDate { get; set; }
        public CartStatus Status { get; set; }
        public enum CartStatus
        {
            Open = 1,
            Confirmed = 2,
            Shipped = 3,
            Received = 4
        }
    }

2

您将性别用于asp-items =“ Html.GetEnumSelectList -GenderType-()”而不是GenderType

例如asp-items =“ Html.GetEnumSelectList -Gender-()”


1

在DropDownList中选择了选项时,需要一种情况进行编辑

将枚举与ASP.NET 5(MVC 6)结合使用选择TagHelper

public enum Gender {
  [Display(Name = "Male")]Male = 1,
  [Display(Name = "Female N")]Female = 2,
  [Display(Name = "Other")]Other = 3 
}

**对于编辑案例:

@Html.DropDownListFor(m => m, Html.GetEnumSelectList(typeof(Gender)))
@Html.DropDownListFor(m => m.Gender, Html.GetEnumSelectList<Gender>()))

@Html.DropDownListFor(m => m.Gender, Html.GetEnumSelectList<Gender>(), "Select", new { @class = "form-control" })

**对于正常情况:

<select asp-for="Gender" asp-items="@Html.GetEnumSelectList<Gender>()">
   <option selected="selected" value="">Please select</option>
</select>

<select asp-for="Gender" asp-items="ViewBag.Genders"></select>

@Html.DropDownList("Gender", Html.GetEnumSelectList<Gender>(), "Select", new { @class = "form-control" })

0

这是在netcore 3中使用枚举实现Custom TagHelper DropDownList的方法

 <radio-button-enum asp-for="@Model.Status" value="@Model.Status"></radio-button-enum>


/// <summary>
/// <see cref="ITagHelper"/> implementation targeting &lt;enum-radio-button&gt; elements with an <c>asp-for</c> attribute, <c>value</c> attribute.
/// </summary>
[HtmlTargetElement("radio-button-enum", Attributes = RadioButtonEnumForAttributeName)]
public class RadioButtonEnumTagHelper : TagHelper
{
    private const string RadioButtonEnumForAttributeName = "asp-for";
    private const string RadioButtonEnumValueAttributeName = "value";

    /// <summary>
    /// Creates a new <see cref="RadioButtonEnumTagHelper"/>.
    /// </summary>
    /// <param name="generator">The <see cref="IHtmlGenerator"/>.</param>
    public RadioButtonEnumTagHelper(IHtmlGenerator generator)
    {
        Generator = generator;
    }

    /// <inheritdoc />
    public override int Order => -1000;

    [HtmlAttributeNotBound]
    [ViewContext]
    public ViewContext ViewContext { get; set; }

    protected IHtmlGenerator Generator { get; }

    /// <summary>
    /// An expression to be evaluated against the current model.
    /// </summary>
    [HtmlAttributeName(RadioButtonEnumForAttributeName)]
    public ModelExpression For { get; set; }

    [HtmlAttributeName(RadioButtonEnumValueAttributeName)]
    public Enum Value { get; set; }

    /// <inheritdoc />
    /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (output == null)
        {
            throw new ArgumentNullException(nameof(output));
        }

        var childContent = await output.GetChildContentAsync().ConfigureAwait(true);
        string innerContent = childContent.GetContent();
        output.Content.AppendHtml(innerContent);

        output.TagName = "div";
        output.TagMode = TagMode.StartTagAndEndTag;
        output.Attributes.Add("class", "btn-group btn-group-radio");
        
        var modelExplorer = For?.ModelExplorer;
        var metaData = For?.Metadata;

        if (metaData?.EnumNamesAndValues != null)
        {
            foreach (var item in metaData.EnumNamesAndValues)
            {
                string enumId = $"{metaData.ContainerType.Name}_{metaData.PropertyName}_{item.Key}";
                string enumInputLabelName = item.Key.ToString();

                bool enumIsChecked = false;
                if (Value != null)
                {
                    if (enumInputLabelName == Value.ToString())
                    {
                        enumIsChecked = true; }
                }
                else
                {
                    if (For.Model != null && enumInputLabelName == For.Model.ToString())
                    {
                        enumIsChecked = true;
                    }
                }

                var enumResourcedName = metaData.EnumGroupedDisplayNamesAndValues.FirstOrDefault(x => x.Value == item.Value);
                if (enumResourcedName.Value != null)
                {
                    enumInputLabelName = enumResourcedName.Key.Name;
                }

                var enumRadio = Generator.GenerateRadioButton(
                    ViewContext,
                    For.ModelExplorer,
                    metaData.PropertyName,
                    item.Key,
                    false,
                    htmlAttributes: new { @id = enumId });
                enumRadio.Attributes.Remove("checked");
                if (enumIsChecked)
                {
                    enumRadio.MergeAttribute("checked", "checked");
                }
                output.Content.AppendHtml(enumRadio);

                var enumLabel = Generator.GenerateLabel(
                    ViewContext,
                    For.ModelExplorer,
                    For.Name,
                    enumInputLabelName,
                    htmlAttributes: new { @for = enumId, @Class = "btn btn-default" });
                output.Content.AppendHtml(enumLabel);
            }
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.