Скорая Компьютерная Помощь г. Калуга

Полный спектр компьютерных услуг!

Здравствуйте, гость ( Вход | Регистрация )

> Внимание!

  • Вся информация, расположенная в данном и других разделах форума получена из открытых источников (интернет-ресурсы, средства массовой информации, печатные издания и т.п.) и/или добавлена самими пользователями. Администрация форума предоставляет его участникам площадку для общения / размещения файлов / статей и т.п. и не несет ответственности за содержание сообщений, а также за возможное нарушение авторских, смежных и каких-либо иных прав, которое может повлечь за собой информация, содержащаяся в сообщениях.
Ремонт компьютеров в калуге Рекламное место сдается
 
Ответить в эту темуОткрыть новую тему
> Перегружаем стандартные DataAnnotation атрибуты для использования с custom resource provider
Decker
сообщение 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).

Читать дальше


--------------------

Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

Рекламное место сдается Рекламное место сдается
Текстовая версия Сейчас: 30.1.2025, 0:13
Рейтинг@Mail.ru
Яндекс.Метрика Яндекс цитирования