Как я могу оставаться СУХОЙ с моделями просмотра asp.net mvc и атрибутами аннотации данных?

Как я могу оставаться DRY с помощью моделей представления asp.net mvc и атрибутов аннотации данных (валидация, отображение и моделирование данных) с помощью Asp.Net MVC? Я передал объектам модели, а также модели конкретных действий для просмотра. Я нахожу оба направления, чтобы иметь некоторые проблемы, пытаясь оставаться сухими.

  • Использовать объекты модели в качестве модели вашего представления:. Это прекрасно работает в простых ситуациях и позволяет только писать атрибуты аннотации данных один раз, на каждом объекте модели. Проблема возникает, когда у вас есть сложные представления, для которых требуется несколько типов объектов. Результирующая архитектура модели представления - это путаница использования классов модели представления и реальных классов моделей. Кроме того, этот метод может отображать свойства модели для вашего представления, которое вы не намерены.

  • Использовать уникальный класс модели представления для каждого действия: Класс модели представления содержит только определенные свойства вида, украшенные атрибутами аннотации данных. По моему опыту, этот метод не оказался очень сухим, поскольку атрибуты аннотации данных, как правило, дублируются в классах моделей представлений. Например, модели просмотра "Новое" и "Редактировать" разделяют много, но не все, свойств и аннотаций данных.

Как я могу оставаться DRY с моделями просмотра asp.net mvc и атрибутами аннотации данных?

3 ответа

До сих пор я обнаружил, что использование наследования для объединения общих свойств работает лучше всего. Я использую уникальный класс представления за действие и до сих пор очень доволен решением. Он не решает 100% случаев, но он охватывает большинство и почти устраняет дубликаты атрибутов контракта.


Хорошим вариантом было бы перейти от DataAnnotations к Fluent Validation. Он позволяет инкапсулировать общую логику проверки в классе, который вы можете применить позже к своим моделям.

Из документации:

[Validator(typeof(PersonValidator))]
public class Person {
 public int Id { get; set; }
 public string Name { get; set; }
 public string Email { get; set; }
 public int Age { get; set; }
}
public class PersonValidator : AbstractValidator<person> {
 public PersonValidator() {
 RuleFor(x => x.Id).NotNull();
 RuleFor(x => x.Name).Length(0, 10);
 RuleFor(x => x.Email).EmailAddress();
 RuleFor(x => x.Age).InclusiveBetween(18, 60);
 }
}
</person>


У меня есть метаданные, определенные в С# следующим образом:

public class Meta
{
 public class Client
 {
 public class Name
 {
 public const bool Required = true;
 public const DataType Type = DataType.Text;
 public const int MaxLength = 30;
 public const int MinLength = 1;
 public const string Regex = @"^[\w\d\.-_]{1,30}$";
 }
 public class Email
 {
 public const bool Required = false;
 public const DataType Type = DataType.EmailAddress;
 public const int MaxLength = 256;
 public const int MinLength = 4;
 public const string Regex = @"^.+@.+$";
 }
 }
}

объявляя их как константы, вы можете использовать DataAnnotations как для BL-объектов, так и для моделей пользовательского интерфейса:

[DataContract]
[Serializable]
public class ClientInfo
{
 [DataMember]
 [Required(AllowEmptyStrings = !Meta.Client.Name.Required)]
 [StringLength(Meta.Client.Name.MaxLength, MinimumLength = Meta.Client.Name.MinLength)]
 [RegularExpression(Meta.Client.Name.Regex)]
 public string Name { get; set; }
 ...
}

ну да, вы дублируете атрибуты, но не метаданные! В addtition у меня есть тривиальный препроцессор для генерации sql-скриптов из шаблона (специальная обработка для *.Required и т.д.):

создать таблицу dbo.Client(   Имя nvarchar ({# Client.Name.MaxLength}) {# Client.Name.Required},   Электронная почта nvarchar ({# Client.Email.MaxLength}) {# Client.Email.Required}, ....

В пользовательском интерфейсе вы можете использовать наследование, чтобы не дублировать свойства. Например, если у вас есть модель с 10 свойствами, но вам нужно отредактировать только 2 из них, создайте EditModel и наследуйте ViewModel от него. Ключ здесь состоит в том, чтобы иметь метаданные в одном хранилище и использовать его как можно больше. Надеюсь, вы получите эту идею.

licensed under cc by-sa 3.0 with attribution.