在 ASP.NET MVC 核中对下拉列表使用枚举

我尝试使用 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.GetEnumSelectList之后,GenderType不被识别,并显示为一个错误。

有人知道怎么解决吗?

88207 次浏览

GenderType is your property name, not the Enum type. The GetEnumSelectList method expects you to give it the type of the Enumeration, not the name of the property in your model.

Try this:

Html.GetEnumSelectList<Gender>()

I got the same problem, I burned my head looking for a solution!

You can solve this situation, instantiating you model on top of your view like:

@using CRM.Model;

@using YourSolution.Model

Yes, it sounds too strange but belive me, it works! See my answer on my own post.

Select ENUM Tag Helper in ASP.NET Core MVC

You can simply use Razor syntax:

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

I think you accidentally used GenderType instead of Gender. The correct syntax is

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

you use Gender to asp-items="Html.GetEnumSelectList -GenderType- ()" instead of GenderType

such as asp-items="Html.GetEnumSelectList -Gender- ()"

The below was what worked for me. This is necessary and the way it is because the enum itself is a class declared under the scope of the class which you are using as a model.

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

below my model (work in progress) for reference

 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
}
}

There needs one case for editing case when there is selected option in DropDownList

Using enums with the ASP.NET 5 (MVC 6) Select TagHelper

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

**For Editing Case:

@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" })

**For Normal Case:

<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" })

This is the way to implement Custom TagHelper DropDownList with enum in netcore 3

 <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);
}
}
}
}