Uso de enumeración para la lista desplegable en ASP.NET MVC Core

83

Estoy tratando de crear una lista desplegable con una propiedad de enumeración en ASP.NET MVC Core usando el asistente de etiquetas en una vista de Razor:

Aquí está el modelo:

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
}

Aquí es parte de un formulario en la vista:

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

El problema que tengo es que después Html.GetEnumSelectList, GenderTypeno se reconoce y aparece como un error.

Alguien sabe cómo resolver esto?

David Sharpe
fuente
2
intente especificarlo como ... @ (Html.GetEnumSelectList <GenderType> ()) "
KD

Respuestas:

122

Creo que accidentalmente usaste en GenderTypelugar de Gender. La sintaxis correcta es

<select asp-for="GenderType" asp-items="Html.GetEnumSelectList<Gender>()">
    <option selected="selected" value="">Please select</option>
</select>
Kostas
fuente
11
Esta debería ser la respuesta, utiliza los ayudantes de etiquetas modernos Y le muestra cómo implementar GetEnumSelectList <Enum> () para construir el elemento de la lista.
Bryan Halterman
Primera sugerencia que funcionó para mí en .net core gracias
rogue39nin
67

GenderTypees el nombre de su propiedad, no el tipo Enum. El método GetEnumSelectList espera que le des el tipo de Enumeración, no el nombre de la propiedad en tu modelo.

Prueba esto:

Html.GetEnumSelectList<Gender>()
ADyson
fuente
Es posible que deba marcarlo como metadatos en el asp-for como: Html.GetEnumSelectList <GenderType.Meta.Gender> () .. El OP no marcó qué versión del marco MVC se usa
Mikael Puusaari
Probé Html.GetEnumSelectList <Gender> () y Html.GetEnumSelectList <enum Gender> () - ambos aparecen como errores
David Sharpe
1
¿Qué error obtienes cuando usas mi ejemplo anterior? ¿El mismo? No creo que su segundo ejemplo sea una sintaxis válida
ADyson
8
En la maquinilla de afeitar, debe rodear por (): @ (Html.GetEnumSelectList <Gender> ()); Debido a que interpreta afeitar el <> como etiquetas HTML de otro modo
dyesdyes
@ADyson, ¿podrías ver esto por favor? stackoverflow.com/questions/48094102/…
26

Simplemente puede usar la sintaxis de Razor:

@Html.DropDownList("StudentGender", 
    Html.GetEnumSelectList<Gender>(),
    "Select Gender",new { @class = "form-control" })
Faishal Ahammad
fuente
1
¡Esto es realmente lo que necesitamos!
juFo
7

¡Tengo el mismo problema, me quemé la cabeza buscando una solución!

Puede resolver esta situación, instanciando su modelo en la parte superior de su vista como:

@using CRM.Model;

@utilizando YourSolution.Model

Sí, suena demasiado extraño, pero créeme, ¡funciona! Vea mi respuesta en mi propia publicación.

Seleccione ENUM Tag Helper en ASP.NET Core MVC

Rogerio Azevedo
fuente
6

Lo siguiente fue lo que funcionó para mí. Esto es necesario y así es porque la enumeración en sí es una clase declarada bajo el alcance de la clase que está utilizando como modelo.

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

debajo de mi modelo (trabajo en progreso) como referencia

 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
        }
    }
Daniel Paiva
fuente
2

utiliza Gender para asp-items = "Html.GetEnumSelectList -GenderType- ()" en lugar de GenderType

como asp-items = "Html.GetEnumSelectList -Gender- ()"

Mehdi
fuente
1

Se necesita un caso para editar el caso cuando hay una opción seleccionada en DropDownList

Usando enumeraciones con ASP.NET 5 (MVC 6) Seleccione TagHelper

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

** Para editar caso:

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

** Para caso normal:

<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" })
Minh Nguyen Van
fuente
0

Esta es la forma de implementar Custom TagHelper DropDownList con enumeración en 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);
            }
        }
    }
}
Minh Nguyen Van
fuente