ASP.NET MVC: Отображаем Enum в Html.DropDownListFor
Сайтостроение | создано: 10.07.2012 | опубликовано: 10.07.2012 | обновлено: 13.01.2024 | просмотров: 13397
Наверное трудно себе представить более или менее серьёзный проект без использования Enum. Я покажу как можно отобразить на представлении (View) любой Enum с локализацией через Resource-файл и/или через DisplayAttribute.
В качестве вступления
Наверное вам не раз приходилось использовать Enum в своих проектах на ASP.NET MVC. И могу предположить, что при редактировании и добавления новой сущности, у которой свойство являло собой перечисление (Enum), вам приходилось выдумывать разные "приспособления". Скажу честно, мне тоже пришлось “покувыраться” с перечислениями (Enum). После непродолжительных танцев с бубнами, я в очередной раз расширил функционал nuget-пакета MvcTools, добавив в сборку Html.EnumDropDownListFor. Об этом расширении и пойдет речь.
Модель на сцену!
Допустим, у меня есть модель, которую надо редактировать. Одно из свойств класса Country типа Enum.
public class Person { /// <summary> /// Идентификатор /// </summary> [Display(Name = "Идентификатор")] [Required(ErrorMessage = "Идентификатор - обязательно поле")] public int Id { get; set; } /// <summary> /// Наименование /// </summary> [Display(Name = "Наименование")] [Required(ErrorMessage = "Наименование - обязательно поле")] [StringLength(50, ErrorMessage = "Наименование не может длиннее 50 символов")] public String Name { get; set; } /// <summary> /// Наименование для меню /// </summary> [Display(Name = "Наименование для меню")] [Required(ErrorMessage = "Наименование для меню - обязательно поле")] [StringLength(50, ErrorMessage = "Наименование для меню не может длиннее 50 символов")] public String DisplayName { get; set; } /// <summary> /// Страна /// </summary> [Display(Name = "Страна")] [Required(ErrorMessage = "Страна - обязательно поле")] public Country Country { get; set; } /// <summary> /// Дата регистрации /// </summary> [Display(Name = "Дата регистрации")] [Required(ErrorMessage = "Дата регистрации - обязательно поле")] [DataType(DataType.Date)] public DateTime CreatedAt { get; set; } }
Само перечисление имеет вид:
public enum Country { Russia, USA, Canada }
В метод контролера добавлю некоторые данные для примера:
List<Person> _list = new List<Person>() { new Person { Country = Country.Russia, CreatedAt = new DateTime(2012,1,5), DisplayName = "Василий", Id =1042, Name = "Vasiliy"}, new Person { Country = Country.Canada, CreatedAt = new DateTime(2012,1,15), DisplayName = "Иван", Id =122, Name = "Ivan"}, new Person { Country = Country.USA, CreatedAt = new DateTime(2012,2,3), DisplayName = "Коля", Id =12, Name = "Nic"} };
Покажите представление
Представление по умолчанию отобразит что-то типа этого:
Если открыть страницу редактирования, например, первого “Василия”, то я увижу следующее:
Заметно, наверное, что не очень похоже на выпадающий список. Попробуем теперь применить хелпер из nuget-пакета MvcTools:
<div class="editor-label"> @Html.LabelFor(model => model.Country) </div> <div class="editor-field"> @Html.EnumDropDownListFor(model => model.Country) @Html.ValidationMessageFor(model => model.CreatedAt) </div>
Обратите внимание на строку номер 5. Это расширение из библиотеке. Теперь уже гораздо лучше:
Локализация Enum (способ 1)
А теперь научим этот EnumDropDownList “говорить” по-русски. Для этого достаточно просто отметить каждое из значений перечисления атрибутом DisplayAttribute из сборки DataAnnotation.
public enum Country { [Display(Name="Российская федерация")] Russia, [Display(Name="Америка")] USA, [Display(Name = "Канада")] Canada }
Ну, вот! Уже совсем другое дело! Дальше – больше!
Локализация Enum (способ 2)
А если хочется большего? Например, использовать ресурсные файлы? Легко! Для начала сразу применим атрибут DisplayAttribute, только теперь немного по-другому:
public enum Country { [Display(ResourceType=typeof(Resources))] Russia, [Display(ResourceType = typeof(Resources))] USA, [Display(ResourceType = typeof(Resources))] Canada }
Раз используем ресурный файл – надо бы его создать.
Ключевые моменты помечены на картинке. Запускаем!
Работает!!! Только надо бы сделать одно важное примечание: ресурсный файл имеет больший приоритет перед первым способом. То есть, если задан ресурс, [Display(Name=”…”)] игнорируется.
В качестве заключения
К сожалению, пока нет времени сделать поддержку глобализации в ресурсных файлах (типа Resources.en-US.resx или resources.fr-FR.resx), но такая работа запланирована.