Load a Dropdownlist based on an Enum - Asp.net core

Asked

Viewed 3,799 times

2

I have a Personal E-nature that relates to the Person table. I need to create a dropdownlist in my view that displays the list of Personsnaturezas (PESSOA FÍSICA E PESSOA JURÍDICA), including showing people related to the current record, according to the viewmodel. Someone knows how to help me?

Personal nature

 public enum PessoaNatureza
 {
     [Description("FÍSICA")]
     Fisica = 1,
     [Description("JURÍDICA")]
     Juridica = 2
 }

Personal

 public class PessoaViewModel
 {
     [Key]
     [DisplayName("Código")]
     public int Id { get; set; }

     [DisplayName("Natureza")]
     [Display(Name = "Natureza")]
     [RegularExpression(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$")]
     [Required(ErrorMessage = "Escolha uma Natureza de Pessoa")]
     public int PessoaNaturezaId { get; set; }
     public List<SelectListItem> PessoasNaturezas { get; set; }
  }

Edit.cshtml

 <div class="form-group">
      <label asp-for="PessoaNaturezaId" class="col-md-2 control-label"></label>
      <div class="col-md-2">
          <input asp-for="PessoaNaturezaId" class="form-control" />
          @Html.DropDownListFor(model => model.PessoaNaturezaId, Model.PessoaNatureza, "--Selecione--", new { @class = "form-control" })
          <span asp-validation-for="PessoaNaturezaId" class="text-danger"></span>
      </div>
  </div>
  • related: https://stackoverflow.com/questions/61953/how-do-you-bind-an-enum-to-a-dropdownlist-control-in-asp-net

  • other: https://answall.com/questions/95375/choose-quais-itens-de-um-enumerador-aparece-em-um-enumdropdownlistfor

2 answers

3


You can create a class static and manipulate their Enum to popular his SelectListItem

public static class ExtensaoDeEnumerador
{
    public static string GetEnumDescription<T>(string value)
    {
        Type type = typeof(T);
        var name = Enum.GetNames(type).Where(f => f.Equals(value, StringComparison.CurrentCultureIgnoreCase)).Select(d => d).FirstOrDefault();

        if (name == null)
        {
            return string.Empty;
        }

        var field = type.GetField(name);
        var customAttribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
        return customAttribute.Length > 0 ? ((DescriptionAttribute)customAttribute[0]).Description : name;
    }

    public static IEnumerable<SelectListItem> EnumToSelectList<T>(string tipoCase = null)
    {
        return (Enum.GetValues(typeof(T)).Cast<T>().Select(
            e => new SelectListItem()
            {
                Text = (tipoCase == null ? GetEnumDescription<T>(e.ToString()) : (tipoCase.ToUpper() == "U" ? GetEnumDescription<T>(e.ToString()).ToUpper() : GetEnumDescription<T>(e.ToString()).ToLower())),
                Value = e.ToString()
            })).ToList();
    }
}

See the call.

pessoaViewModel.PessoasNaturezas = ExtensaoDeEnumerador.EnumToSelectList<PessoaNatureza>("U").OrderBy(x => x.Text);
  • Marconcilio, the loading part of the dropdownlist worked, only when it opens the record, it does not give the Binding to relate the correct type of person... What should I do?

  • You have to tell him what he is.. Personal ViewModel.PeopleNaturezas.Where(x => x.Value.Equals(personViewModel.PeopleNatureza.Tostring())). Firstordefault(). Selected = true;

1

Here is another option, although I prefer the Marconcilio approach, for solving the functionality as a whole and not just this one-off issue. But I also do not agree very much with the structure presented in the question.

You can add a constructor to your Viewmodel where you populate the List<SelectListItem> PessoasNaturezas with Enum values and marks as selected the value populated in PessoaNaturezaId.

public class PessoaViewModel
{
    [Key]
    [DisplayName("Código")]
    public int Id { get; set; }

    [DisplayName("Natureza")]
    [Display(Name = "Natureza")]
    [RegularExpression(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$")]
    [Required(ErrorMessage = "Escolha uma Natureza de Pessoa")]
    public int PessoaNaturezaId { get; set; }
    public List<SelectListItem> PessoasNaturezas { get; set; }

    public PessoaViewModel()
    {
        var listaPessoaNatureza = from PessoaNatureza pn in Enum.GetValues(typeof(PessoaNatureza))
                                  select new SelectListItem
                                  {
                                      Value = ((int)pn).ToString(),
                                      Text = Enum.GetName(typeof(PessoaNatureza), pn),
                                      Selected = PessoaNaturezaId == (int)pn ? true : false
                                  };
        PessoasNaturezas = listaPessoaNatureza.ToList();
    }
}

And in your view you can maintain the default helpers using the <select asp-for..

<div class="form-group">
    <label asp-for="PessoaNaturezaId" class="col-md-2 control-label"></label>
    <div class="col-md-2">
        <select asp-for="PessoaNaturezaId" asp-items="Model.PessoasNaturezas">
            <option value="">--Selecione--</option>
        </select>
        <span asp-validation-for="PessoaNaturezaId" class="text-danger"></span>
    </div>
</div>

This "solves" your problem, but I recommend that you opt for the solution presented by your colleague. I only recommend my proposal if I have difficulties in understanding or implementing the other suggestion.

  • Thanks for the contribution Leandro!

  • Leandro, I’m trying to create a Generica function to set the Selected property to make the Binding correctly... Only Enum is generic <T>... like I know it???

  • public Static Ienumerable<Selectlistitem> Enumtoselectlist<T>(string typeCase = null, string Selected = null) { Return (Enum.Getvalues(typeof(T)).Cast<T>().Select( e => new Selectlistitem() { Text = (typeCase == null ? Getenumdescription<T>(e.Tostring()) : (tipoCase.ToUpper() == "U" ? GetEnumDescription<T>(e.ToString()).ToUpper() : GetEnumDescription<T>(e.ToString()).ToLower())),&#xA; Value = e.ToString(),&#xA; Selected = ???????????????????????&#xA; })). Tolist(); }

  • @Jalberromano, that would be another question... but in the case of the other answer the identification of Selected would be in the View or in a loop in the Controller. Or you create an Overload by receiving this parameter and implement it in the Extensaodeenumerator. (As I said before, I left my answer in case you encountered difficulties with the other)

  • I load my viewmodel in the Application layer, in the Personal Service class, to be exact. In my getById method, I select everything there and take the opportunity to call the class Extensaodeenumerator, load the Dropdownlist and set the property "Selected" with Personnaturezaid... I was having difficulty setting it, because my Num was going like 1 and there in the class, at the time of comparing, the variable was like "physics".... " 1" is different from "physics". I changed and worked 100%

  • Anyway, I am grateful for your help and also to @Marconcilio!!!

  • I have an error here.. Asp-items="Model.Categories". Cannot convert type implicitly . you know what I can do?

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.