MVC, ViewModels и проверка - PullRequest
       62

MVC, ViewModels и проверка

4 голосов
/ 31 декабря 2010

Я создаю приложение MVC3 с EF4, используя POCO. Я добавил атрибуты проверки в мои сущности EF. Теперь, когда я строю виды, я хочу использовать модель вида (и, возможно, использовать AutoMapper для их заполнения).

Проблема, с которой я столкнулся, заключается в том, что я должен переопределить свои атрибуты проверки в моей модели представления, которая нарушает принцип DRY. Например, если я решу изменить размер поля, мне придется изменить атрибут MaxLength как в POCO, так и в любых моделях представления, которые его используют.

Есть ли какой-нибудь хитрый способ сопоставления правил проверки из моих POCO с моей моделью представления?

Ответы [ 3 ]

5 голосов
/ 01 января 2011

Лично я выполняю валидацию при просмотре моделей.Это то, что контроллер получает от представления, и это класс, который содержит пользовательский ввод.Я различаю два типа правил валидации: поверхностная валидация и бизнес-валидация.Правила, такие как обязательные поля, надлежащие форматы, должны применяться в моделях представления, тогда как бизнес-правила, такие как пользователь с данным именем, уже существует в базе данных, должны быть проверены на модели.

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

2 голосов
/ 10 марта 2011

Один подход, который получает некоторую абстракцию, состоит в том, чтобы ViewModel был «составлен» из класса вашей бизнес-модели, включая другую необходимую вам информацию представления.

class MyObject 
{
    public int ID {get;set}

    [Required]
    [StringLength(512)]     
    public string Name {get;set;}

}

class MyViewModel // ViewModel for a specific view 
{
    public MyObject MyModel {get;set;}        // the model that is being edited 

    // other data the view might need, set by the controller 
    public string SomeMessage { get; set; }
    public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list

}

Затем в представлении ссылаются на ViewModel соответственно.

@model My.Namespace.MyViewModel


Hello @model.MyModel.Name !!!

Таким образом, вы только указываете валидацию и / или аннотации данных в своем бизнес-классе в одном месте.

Если вы хотите иметь другую валидацию, тогда потребуется некоторая стратегия для выборочного применения логики валидации.

1 голос
/ 01 января 2011

Я тоже борюсь с этим, и я согласен, что это нарушает СУХОЙ. Я опубликовал недавний вопрос об этом Здесь и получил довольно небольшой откат.

Вы никогда не сможете получить идеальную СУХУЮ в любом реальном приложении. Иногда ты получаешь больше пользы от нарушения принципа, чем от слепого следования ему.

EDIT:

Можно также считать, что DRY может нарушать принцип единой ответственности (SRP). Повторно используя подобный код, вы теперь заставляете код выполнять больше чем одно. Если вы подумаете о том, что модели данных и модели представлений имеют разные цели и, следовательно, разные обязанности ... объединение их в единую модель нарушает SRP. То есть, делая вашу модель данных также моделью представления, это две разные обязанности.

Теперь можно придумать несколько способов потенциально примирить SRP с DRY в этом отношении, но в какой-то момент вы должны взвесить выгоды от стоимости.

...