2015-04-13 10 views
7

Jestem nowy w asp.net MVC. Próbuję użyć kontroli rozwijanej na mojej stronie widoku, która zapełnia się z enum. Chcę również dodać niestandardowe opisy do wartości rozwijanych. Przeszukałem wiele przykładów, ale nikt nie pisał, jak wypełnić opis na stronie widoku. Tu jest mój kodu:jak używać enum z DescriptionAttribute w asp.net mvc

ViewModel:

public enum SearchBy 
    { 
     [Description("SID/PID")] 
     SID = 1, 
     [Description("Name")] 
     Name, 
     [Description("Birth Date")] 
     DOB, 
     [Description("Cause#")] 
     Cause 
    } 

Index.cshtml

<div class="form-horizontal"> 
    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
    <div class="form-group form-inline"> 
     @Html.LabelFor(model => model.searchBy, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EnumDropDownListFor(model => model.searchBy, "Search By", htmlAttributes: new { @class = "form-control" }) 
      @Html.TextBox("searchByVal", null, htmlAttributes: new { @placeholder = "SID/PID ", @class = "form-control" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @placeholder = "First Name", @class = "form-control" } }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @placeholder = "Last Name", @class = "form-control" } }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.DOB, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @placeholder = "Birth Date", @class = "form-control" } }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.CauseNumber, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.CauseNumber, new { htmlAttributes = new { @placeholder = "Cause#", @class = "form-control" } }) 
     </div> 
    </div> 

    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Search" class="btn btn-block btn-primary" /> 
     </div> 
    </div> 
</div> 

Nie wypełniania pola opisu, jak wspomniano w moim SearchBy wyliczenia. zobacz zdjęcie tutaj. http://postimg.org/image/phdxgocj7/ Proszę mi pomóc, gdzie popełniam błąd. Dziękujemy

AKTUALIZACJA: Mam rozwiązanie tego od Nico. I trochę się o tym dowiedziałem. Aktualizuję ten wpis, ponieważ może być przydatny dla innych osób, które są nowe w firmie MVC http://weblogs.asp.net/jongalloway//looking-at-asp-net-mvc-5-1-and-web-api-2-1-part-1-overview-and-enums

Dziękuję wszystkim. Ciesz kodowania ..

+0

Nie ma 'EnumDropDownListFor()' metoda w MVC -4. Masz na myśli MVC-5, czy jest to niestandardowy pomocnik? –

+0

Przepraszamy, zaktualizowałem tag. Tak, używam MVC-5 –

Odpowiedz

16

HTML pomocnika EnumDropDownListFor lub EnumDropDownList nie uwzględniać Description atrybutu dekoracje na członków enum. Jednak przeglądając kod źródłowy:

Enum rozwijane Lista Helper: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs

Enum Helper klasy: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs

wyliczenia klas pomocniczych powyżej służą do konwersji Enum do List<SelectListItem>. Z poniższym kodzie:

// Return non-empty name specified in a [Display] attribute for the given field, if any; field's name otherwise 
private static string GetDisplayName(FieldInfo field) 
{ 
    DisplayAttribute display = field.GetCustomAttribute<DisplayAttribute>(inherit: false); 
    if (display != null) 
    { 
     string name = display.GetName(); 
     if (!String.IsNullOrEmpty(name)) 
     { 
      return name; 
     } 
    } 

    return field.Name; 
} 

Widać, że w metodzie GetDisplayName to sprawdza istnienie DisplayAttribute na członka enum. Jeśli istnieje atrybut wyświetlania, nazwa jest ustawiana na wynik metody DisplayAttribute.GetName().

Kładzenie to razem możemy modyfikować enum używać DisplayAttribute zamiast DescriptionAttribute i ustawiając właściwość na wartość, którą chcesz wyświetlić Name.

public enum SearchBy 
{ 
    [Display(Name = "SID/PID")] 
    SID = 1, 
    [Display(Name = "Name")] 
    Name, 
    [Display(Name = "Birth Date")] 
    DOB, 
    [Display(Name = "Cause#")] 
    Cause 
} 

Daje to pożądany wynik.

enter image description here

Nadzieja to pomaga.

+0

Dziękuję Nico. Pomaga to, ale na stronie widoku, co powinienem zastąpić EnumDropDownListFor? –

+0

Po nieco badań, rozumiem, że muszę napisać szablon wyświetlania do renderowania Enum, aby wyświetlić jako rozwijanego, prawda? Popraw mnie, jeśli się mylę. Znalazłem artykuł na ten temat tutaj: http://www.codeproject.com/Articles/776908/Dealing-with-Enum-in-MVC –

1

Dane:

public enum MyEnum 
{ 
    [Description("This is the description if my member A")] 
    A, 
    [Description("This is the description if my member B")] 
    B 
} 

Ja osobiście skorzystać z tej metody rozszerzenie dostać opis z mojego wyliczenia:

public static string GetDescription(this Enum value) 
     { 
      FieldInfo fi = value.GetType().GetField(value.ToString()); 

      DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 

      if (attributes != null && attributes.Length > 0) 
      { 
       return attributes[0].Description; 
      } 
      else 
      { 
       return value.ToString(); 
      } 
     } 

Aby go użyć:

MyEnum.A.GetDescription(); 

nadzieję, że to pomaga.

+0

Dziękuję Andrew. Nico pomógł mi w rozwiązaniu problemu. –

0

Utworzono klasę pomocniczą, która próbuje różnych typów atrybutów. Potrzebowałem go, bo był przy bootstrap z https://github.com/civicsource/enums i https://silviomoreto.github.io/bootstrap-select/

public static class EnumHelper<T> 
    { 
     static EnumHelper() 
     { 
      var enumType = typeof(T); 
      if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); } 
     } 

     public static string GetEnumDescription(T value) 
     { 
      var fi = typeof(T).GetField(value.ToString()); 
      var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
      return attributes.Length > 0 ? attributes[0].Description : value.ToString(); 
     } 

     public static IEnumerable<SelectListItem> GetSelectList() 
     { 
      var groupDictionary = new Dictionary<string, SelectListGroup>(); 

      var enumType = typeof(T); 
      var fields = from field in enumType.GetFields() 
         where field.IsLiteral 
         select field; 

      foreach (var field in fields) 
      { 
       var display = field.GetCustomAttribute<DisplayAttribute>(false); 
       var description = field.GetCustomAttribute<DescriptionAttribute>(false); 
       var group = field.GetCustomAttribute<CategoryAttribute>(false); 

       var text = display?.GetName() ?? display?.GetShortName() ?? display?.GetDescription() ?? display?.GetPrompt() ?? description?.Description ?? field.Name; 
       var value = field.Name; 
       var groupName = display?.GetGroupName() ?? group?.Category ?? string.Empty; 
       if (!groupDictionary.ContainsKey(groupName)) { groupDictionary.Add(groupName, new SelectListGroup { Name = groupName }); } 

       yield return new SelectListItem 
       { 
        Text = text, 
        Value = value, 
        Group = groupDictionary[groupName], 
       }; 
      } 
     } 
    } 

I ty nazywasz to podoba:

<div class="form-group"> 
    @Html.LabelFor(model => model.Address.State, htmlAttributes: new { @class = "control-label col-md-2" }) 
    <div class="col-sm-4"> 
     @Html.DropDownListFor(model => model.Address.State, EnumHelper<StateProvince>.GetSelectList(), new { @class = "selectpicker show-menu-arrow", data_live_search = "true" }) 
     @Html.ValidationMessageFor(model => model.Address.State, "", new { @class = "text-danger" }) 
    </div> 
</div> 

Result