Что должно быть в моих моделях?

У меня есть бизнес-модели с именем Product и Category, как показано ниже, в которых я добавляю проверки:

public class Product
{
    public int ProductId {get; set;}
    [Required]
    [StringLength(25)]
    public string Name {get; set;}
    public string Description {get; set;}
    public int CategoryId {get; set;}
}

public class Category
{
    public int CategoryId {get; set;}
    public string Name {get; set;}
}

Для модели просмотра я создал что-то вроде этого:

public class ProductViewModel
{
    public Product Product {get; set;}
    public IList<Category> Categories  {get; set;}
}

Один мой друг предложил сохранить все проверки в модели представления и отобразить все свойства бизнес-модели в модели представления следующим образом:

public class ProductViewModel
{
    public int ProductId {get; set;}
    [Required]
    [StringLength(25)]
    public string Name {get; set;}
    public string Description {get; set;}
    public int CategoryId {get; set;}
    public IList<SelectListItem> CategoryDropdownValues  {get; set;}
}

Я спросил его о преимуществах этого подхода к вышеупомянутому, он был не очень уверен. Но он настаивал на том, что вы не должны использовать бизнес-модели непосредственно в своих взглядах и что только модели просмотра должны быть проверены.

Мои вопросы:

  • Должен ли я придерживаться логики проверки в моделях или бизнес-моделях?
  • Неужели плохо, если модели просмотра зависят от бизнес-моделей?

Ответ 1

Твой друг прав. О ваших вопросах

  • Подтверждение ввода и проверки бизнес-правил пользователя. В большинстве случаев проверка правильности ввода является частью проверки бизнес-правил, однако в asp.net mvc фреймворк выполняет эту проверку автоматически. Во избежание дублирования это означает, что проверка подлинности пользовательского интерфейса должна использовать проверку бизнеса. Это можно легко сделать с помощью FluentValidations (аннотации данных слишком жесткие IMO).

    Таким образом, в этом случае выполнение пользовательского интерфейса выполняется на уровне пользовательского интерфейса, используя проверку бизнес-модели.

  • Модели для просмотра всегда зависят от бизнес-модели, по крайней мере, до некоторой степени, но не одно и то же. Это разные модели с различными целями, поэтому их следует разделить. Тот факт, что, вероятно, ваша модель взгляда на 90% идентична модели бизнеса (ну, структуры данных), является просто совпадением. Мы хотим сохранить каждую модель в своем собственном слое, и просто случается, что у них одинаковые свойства.

Ответ 2

Валидация должна храниться на уровне домена/бизнеса; в противном случае вы обнаружите, что дублируете правила проверки в течение всего приложения. Это самый низкий общий знаменатель, с которым все ваши сервисные и презентационные слои будут взаимодействовать.

Использование моделей доменов в модели представления представлений - это другая проблема, с плюсами и минусами. В вашем конкретном случае упаковка ваших моделей с помощью конкретной модели представления может облегчить часть дублирования, с которой вы сталкиваетесь. Однако не забудьте "свалить" модели внутри моделей просмотра так, как они могут быть необходимы: это быстро повредит производительность, так как загружается много ненужной информации.

Структура ASP.NET MVC будет правильно анализировать и проверять атрибуты из System.ComponentModel.DataAnnotations пространства имен. Вы можете использовать их для аннотирования моделей своего домена, и при необходимости вы можете при необходимости расширить свою презентационную модель, используя компоненты, ограниченные инфраструктурой MVC.

Ответ 3

Я бы сохранил валидацию в модели представления. То, откуда MVC получает свои метаданные. Кроме того, атрибуты проверки определены в сборках MVC. Вы не хотите добавлять зависимость MVC к своей бизнес-логике или к чему-либо, кроме пользовательского интерфейса. Модели пользовательского интерфейса могут зависеть от бизнес-модели, но не наоборот. Я также предлагаю вам ознакомиться с некоторыми статьями лучших практик, такими как этот: http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx

Ответ 4

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

В базе кода, над которой я работаю, мы использовали этот ярлык много раз для простых моделей. Но, по мере развития кода, вы обнаружите, что вам нужно добавить новые функции в пользовательский интерфейс, который на самом деле не имеет смысла в самой модели. Если вы не добавите эту модель просмотра в настоящее время, наивный программист, несомненно, придет позже и добавит биты пользовательского интерфейса непосредственно к модели.

Для валидаций я согласен, что вы, вероятно, хотите, чтобы на самой модели; это означает, что модель всегда проверяется независимо от того, где она отображается.

Но... могут быть случаи, когда валидации должны быть в модели представления: представьте модель представления, которая отображает список продуктов, и включает в себя поле фильтра, чтобы вы могли сузить список найденных элементов. Если фильтру не разрешено, скажем, "&" символов в нем, то эта проверка будет помещена на модель представления, а не на модель.

Ответ 5

  • Валидация должна выполняться в вашем бизнес-слое
  • Не подвергайте бизнес-модель непосредственно своему пользовательскому интерфейсу

Итак, как вы подтверждаете ввод в пользовательском интерфейсе? -Да, вам нужно в некоторой степени дублировать проверку, используя атрибуты DataAnnotations на моделях просмотра MVC. Я думаю, что это лучше подходит для SRP, поскольку это не то же самое, что проверять веб-ввод и проверять бизнес-правила.

Ответ 6

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