В качестве вступления
Наверное вам не раз приходилось использовать Enum в своих проектах на ASP.NET MVC. И могу предположить, что при редактировании и добавления новой сущности, у которой свойство являло собой перечисление (Enum), вам приходилось выдумывать разные «приспособления». Скажу честно, мне тоже пришлось “покувыраться” с перечислениями (Enum). После непродолжительных танцев с бубнами, я в очередной раз расширил функционал nuget-пакета MvcTools, добавив в сборку Html.EnumDropDownListFor. Об этом расширении и пойдет речь.
Модель на сцену!
Допустим, у меня есть модель, которую надо редактировать. Одно из свойств класса Country типа Enum.
1: publicclass Person { 2: /// <summary> 3: /// Идентификатор 4: /// </summary> 5: [Display(Name = «Идентификатор»)] 6: [Required(ErrorMessage = «Идентификатор — обязательно поле»)] 7: publicint Id { get; set; } 8: 9: /// <summary> 10: /// Наименование 11: /// </summary> 12: [Display(Name = «Наименование»)] 13: [Required(ErrorMessage = «Наименование — обязательно поле»)] 14: [StringLength(50, ErrorMessage = «Наименование не может длиннее 50 символов»)] 15: public String Name { get; set; } 16: 17: /// <summary> 18: /// Наименование для меню 19: /// </summary> 20: [Display(Name = «Наименование для меню»)] 21: [Required(ErrorMessage = «Наименование для меню — обязательно поле»)] 22: [StringLength(50, ErrorMessage = «Наименование для меню не может длиннее 50 символов»)] 23: public String DisplayName { get; set; } 24: 25: /// <summary> 26: /// Страна 27: /// </summary> 28: [Display(Name = «Страна»)] 29: [Required(ErrorMessage = «Страна — обязательно поле»)] 30: public Country Country { get; set; } 31: 32: /// <summary> 33: /// Дата регистрации 34: /// </summary> 35: [Display(Name = «Дата регистрации»)] 36: [Required(ErrorMessage = «Дата регистрации — обязательно поле»)] 37: [DataType(DataType.Date)] 38: public DateTime CreatedAt { get; set; } 39: }
Само перечисление имеет вид:
1: publicenum Country { 2: Russia, 3: USA, 4: Canada 5: }
В метод контролера добавлю некоторые данные для примера:
1: List<Person> _list = new List<Person>() { 2: new Person { Country = Country.Russia, 3: CreatedAt = new DateTime(2012,1,5), 4: DisplayName = «Василий», 5: Id =1042, 6: Name = «Vasiliy»}, 7: new Person { Country = Country.Canada, 8: CreatedAt = new DateTime(2012,1,15), 9: DisplayName = «Иван», 10: Id =122, 11: Name = «Ivan»}, 12: new Person { Country = Country.USA, 13: CreatedAt = new DateTime(2012,2,3), 14: DisplayName = «Коля», 15: Id =12, 16: Name = «Nic»} 17: };
Покажите представление
Представление по умолчанию отобразит что-то типа этого:
Если открыть страницу редактирования, например, первого “Василия”, то я увижу следующее:
Заметно, наверное, что не очень похоже на выпадающий список. Попробуем теперь применить хелпер из nuget-пакета MvcTools:
1: <div class=»editor-label»> 2: @Html.LabelFor(model => model.Country) 3: </div> 4: <div class=»editor-field»> 5: @Html.EnumDropDownListFor(model => model.Country) 6: @Html.ValidationMessageFor(model => model.CreatedAt) 7: </div>
Обратите внимание на строку номер 5. Это расширение из библиотеке. Теперь уже гораздо лучше:
Локализация Enum (способ 1)
А теперь научим этот EnumDropDownList “говорить” по-русски. Для этого достаточно просто отметить каждое из значений перечисления атрибутом DisplayAttribute из сборки DataAnnotation.
1: publicenum Country { 2: [Display(Name=»Российская федерация»)] 3: Russia, 4: [Display(Name=»Америка»)] 5: USA, 6: [Display(Name = «Канада»)] 7: Canada 8: }
Ну, вот! Уже совсем другое дело! Дальше – больше!
Локализация Enum (способ 2)
А если хочется большего? Например, использовать ресурсные файлы? Легко! Для начала сразу применим атрибут DisplayAttribute, только теперь немного по-другому:
1: publicenum Country { 2: [Display(ResourceType=typeof(Resources))] 3: Russia, 4: [Display(ResourceType = typeof(Resources))] 5: USA, 6: [Display(ResourceType = typeof(Resources))] 7: Canada 8: }
Раз используем ресурный файл – надо бы его создать.
Ключевые моменты помечены на картинке. Запускаем!
Работает!!! Только надо бы сделать одно важное примечание: ресурсный файл имеет больший приоритет перед первым способом. То есть, если задан ресурс, [Display(Name=”…”)] игнорируется.
В качестве заключения
К сожалению, пока нет времени сделать поддержку глобализации в ресурсных файлах (типа Resources.en-US.resx или resources.fr-FR.resx), но такая работа запланирована. Желающие поэкспериментировать могут скачать проект.
Подробнее: http://feedproxy.google.com/~r/blogmusor/~3/E462fGiaDr4/88
Источник: