Перегружаем стандартные DataAnnotation атрибуты для использования с custom resource provider |
Здравствуйте, гость ( Вход | Регистрация )
Перегружаем стандартные DataAnnotation атрибуты для использования с custom resource provider |
11.4.2016, 14:17
Сообщение
#1
|
|
Администратор Группа: Главные администраторы Сообщений: 14349 Регистрация: 12.10.2007 Из: Twilight Zone Пользователь №: 1 |
Программирование*, C#*, ASP*, .NET* Представьте, что у вас есть legacy проект Asp.NET MVC версии 5, которому немало лет. В нем используется самописный ResourceProvider, который умеет доставать из базы ресурс и показывать его на UI. В зависимости от различных условий (например, от того, откуда пользователь пришел на сайт), ресурсы будут показаны разные. Теперь пришло время сделать так, чтобы все намертво захардкоженные строки в Data Annotation атрибутах, такие как: [Display(Name = "Username")] [Required(ErrorMessage = "Please enter the username")] [StringLength(64, ErrorMessage = "Username cannot exceed 64 characters")] public string Username{ get; set; } тоже могли получать свои значения, используя ResourceProvider. Как это сделать, используя немного наследования и доступной в Asp.NET MVC кастомизации, я покажу под катом. Вся необходимая логика по нахождению именно того ресурса, который нужно показать в текущей ситуации, инкапсулирована в классе ResourceProvider и связанных с ним классов, поэтому нам достаточно вызвать следующий его метод: string resource = ResourceProvider.GetResource(name); Display attribute DisplayAttribute, появившийся в .NET Framework 4, в отличие от своего предшественника, DisplayNameAttribute, помечен как sealed, поэтому мы не сможем использовать магию наследования в этом случае. Здесь мы воспользуемся тем, что DisplayName также доступен в классе System.Web.Mvc.ModelMetadata. Создадим класс, наследующий от DataAnnotationsModelMetadataProvider, переопределим метод CreateMetadata, чтобы подменить DisplayName на полученный от ResourceProvider. В качестве IoC контейнера используем Ninject. Чтобы задать имя ресурса, создадим свой собственный атрибут DisplayResourceAwareAttribute. public class DisplayResourceAwareAttribute : Attribute { public string ResourceName { get; set; } public DisplayResourceAwareAttribute() { } } public class ResourceAwareMetadataProvider : DataAnnotationsModelMetadataProvider { [Inject] public ResourceProvider ResourceProvider { get; set; } protected override ModelMetadata CreateMetadata( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); var displayNameAttr = attributes.SingleOrDefault(a => typeof(DisplayResourceAwareAttribute) == a.GetType()) as DisplayResourceAwareAttribute; if (displayNameAttr != null) { modelMetadata.DisplayName = ResourceProvider.GetResource(displayNameAttr.ResourceName); } return modelMetadata; } } Вышеприведенный код ищет среди атрибутов атрибут типа DisplayResourceAwareAttribute, и если такой существует, то мы обновим свойство DisplayName значением, полученным с помощью ResourceProvider.GetResource. Теперь мы должны использовать новый MetadataProvider вместо стандартного. Для этого в метод Application_Start в файле Global.asax.cs, добавим следующую строку: protected void Application_Start() { ... ModelMetadataProviders.Current = DependencyResolver.Current.GetService<ResourceAwareMetadataProvider>(); ... } Теперь в модели мы можем избавить от явно заданного описания поля, заменив стандартный атрибут на наш: [DisplayResourceAware(ResourceName = "UsernameResource")] [Required(ErrorMessage = "Please enter the username")] [StringLength(64, ErrorMessage = "Username cannot exceed 64 characters")] public string Username{ get; set; } Никаких дополнительных изменений в представлениях, контроллерах не требуются. Валидационные атрибуты С валидационными атрибутами, такими как Required, StringLength и т.д. проще, потому что мы можем наследовать свои атрибуты от них и в конструкторе установить свойству ErrorMessage нужное нам значение. Original source: habrahabr.ru (comments, light). Читать дальше -------------------- |
|
|
Текстовая версия | Сейчас: 30.1.2025, 0:13 | |