Проверка mpc asp.net при использовании viewmodel - PullRequest
4 голосов
/ 13 декабря 2011

недавно я решил использовать viewmodels вместо EF EntityObjects. Я уверен, что не будет проблем для запросов GET, но я хочу знать, что делать с действиями создания и обновления. Я прочитал много дискуссий и решил, что буду вести себя таким образом . но появились другие вопросы:

1) когда я использовал EF EntityObjects с аннотациями, логика валидации хранилась в одном месте, но если у меня разные видовые модели в разных проектах, мне придется дублировать правила валидации. не является ли это нарушением принципа СУХОЙ?

2) Я прочитал несколько постов о моделях представления и валидации, где люди предлагают проверить входные данные в моделях представления и бизнес-правилах в моделях домена, но я не могу понять, как я могу вызвать проверку, которая определена в моделях домена, если мои действия имеют Модели просмотра в качестве параметров:

public class MyDomainModel : IValidatableObject
{
    public string Title;

    // validation of business rules
}

public class MyViewModel
{
    [Required]
    public string Title;
}

public ActionResult Edit(MyViewModel item)
{
    if (ModelState.IsValid) // MyViewModel's rules are validated not MyDomainModel's
    {
        ...
}

1 Ответ

4 голосов
/ 13 декабря 2011

Если вы переключаетесь на ViewModels, вы должны позволить платформе выполнить проверку через DataAttributes в ваших классах ViewModel. Это просто формальная проверка ввода, тогда вы должны проверить в соответствии с вашими бизнес-правилами (иногда просто аннотациями данных просто невозможно охватить все сценарии), а в случае ошибок добавьте их в состояние модели.

Пример:

public class MyViewModel 
{
   [Required]
   [StringLength(20)]
   [RegularExpression("whatever")]
   public string Foo { get; set; }

   [Required]
   public int Bar { get; set; }

   public bool AFlagNotModifiableButImportant { get; set; }
}

в вашем посте вы можете сделать что-то вроде:

public ActionResult Sample (MyViewModel Obj) 
{
    if (!ModelState.IsValid) {
       return View(Obj);
    }
    // Complex business logi checks in here
    MyBusinessObj BsnObj = new MyBusinessObj(Obj);
    if (!BsnObj.IsValid()) {
      ModelState.AddModelError(string.Empty, "A veery bad error");
      return View(Obj);
    }
    // Perform Heavy Business Logic which creates a new ViewModel (eg. setting the flag property in order to show something important at view level)
    MyViewModel NewOne = BsnObj.DoIt();
    // Return a view with the new Model (can be whatever you want)
    return View(NewOne);
}

Очевидно, я держу это очень просто. Следуя этому шаблону, обязательно добавьте немного накладных расходов в отношении кода, но проверки должны выполняться как на стороне клиента (только формальная проверка на входе), так и на стороне сервера (как формальная, так и семантическая проверка). Я предпочитаю использовать всю семантику в бизнес-сборке, оставляя формальные проверки для ненавязчивого механизма проверки MVC (просто немного сахара в моем представлении, да, я ненавижу Javascript).

Обычно мои бизнес-объекты используют свойства ViewModel, считая их доступными только для чтения (только полезные для предотвращения неправильных инъекций), и выполняют грязную / тяжелую работу.

Возможно, это не идеальное решение для всего, но я заметил, что применение этого паттерна (и вынудить других членов команды сделать то же самое) приводит к хорошей базе кода. Да, мы все еще далеки от совершенства, я бы хотел написать как семантику, так и формальные проверки только один раз, но сейчас именно так работает сеть.

Дайте мне знать, если вам нужен дополнительный совет или я полностью неправильно понял ваш вопрос.

PS: как только вы выберете шаблон, придерживайтесь его, несмотря ни на что.

РЕДАКТИРОВАТЬ: (длинные комментарии нет нет)

В конструкторе я обычно применяю сопоставления к полям, которые мне нужно изменить, я стараюсь рассматривать свойства ViewModel только для чтения, чтобы избежать нежелательных изменений.

Мой метод IsValid() просто содержит бизнес-проверки (например, с помощью идентификатора, который он проверяет на предмет реального существования в определенной таблице, или с помощью имени пользователя проверяет, действительно ли он может получить доступ к определенным данным).

Это просто разделение между проверкой ViewModel (для меня это просто синтаксический => строки - это строки, целое число - целое число, положительные числа> = 0, длины строк соблюдаются, диапазоны соблюдаются и т. Д.) И реальная бизнес-валидность ( semantic => пользователь может получить доступ к некоторым данным, объект является действительным в области приложения).

Конечно, уровень проверки бизнеса также может быть простым (или не существовать вообще), я предпочитаю разделять их для повторного использования (часто моя бизнес-логика разделяется между приложением MVC и приложением WPF). Это немного дополнительная работа, но в долгосрочной перспективе она окупается лучше, я могу везде использовать свою сложную бизнес-логику. (и работа с Банками - это самая большая цель. Измените логику только в одной сборке, например, добавьте новую проверку чего-либо, и будьте уверены, что каждое приложение, использующее эту сборку, будет обновлено).

Так что, определенно, это больше лишняя работа, но я думаю, что лучше потратить несколько часов на разработку, чем тратить дни на техническое обслуживание / развитие.

В настоящее время программирование, по-видимому, сводится к тому, чтобы забыть (из-за сокращения времени / бюджета или просто потому, что мы выполняем свою задачу, а затем меняем сотрудника), но каждая строка, которая закодирована, будет нуждаться в некотором обслуживании будущее, поэтому лучше держать все в порядке и чистоте, предпочитая простоту обслуживания, а не скорость разработки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...