Куда относится проверка ввода в приложении MVC? - PullRequest
22 голосов
/ 15 января 2010

У меня есть приложение MVC, которое получает данные из формы.
Это форма входа в систему, поэтому единственная необходимая проверка состоит в том, чтобы проверить, не является ли ввод непустым.
Прямо сейчас, прежде чем передать его модели, я проверяю его в контроллере.
Это лучшая практика или нет? Это относится к модели?

Ответы [ 7 ]

13 голосов
/ 15 января 2010

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

Есть интересное обсуждение этого на joelonsoftware .

6 голосов
/ 23 февраля 2010

Я долго думал об этом и после попытки поставить валидацию как в контроллерах, так и в моделях ... наконец, я пришел к выводу, что для многих моих приложений ... валидация принадлежит модели, а не в контроллере. Зачем? Поскольку одна и та же модель может в будущем использоваться различными другими вызовами контроллеров или API-интерфейсами ... и тогда мне придется повторять процесс проверки снова и снова. Это нарушит СУХОЙ и приведет ко многим ошибкам. Плюс, с философской точки зрения, это модель, которая взаимодействует с базой данных (или другим постоянным хранилищем) и, таким образом, является своего рода «последним призывом к алкоголю», чтобы сделать это в любом случае.

Поэтому я выполняю перевод get / post в контроллере, а затем отправляю необработанные данные в модель для проверки и обработки. Конечно, я часто занимаюсь веб-приложениями на php / mysql, и если вы занимаетесь чем-то другим, результаты могут отличаться. Надеюсь, это кому-нибудь поможет.

1 голос
/ 15 января 2017

Валидация должна быть в модели

Только модель знает «детали» бизнеса. только модель знает, какие данные являются приемлемыми, а какие - нет. контроллер просто знает, как «использовать» модель.

например: допустим, нам нужна функциональность регистрации новых пользователей в нашей системе.

Модель:

 public function registerUser(User $user){
    //pseudo code
       //primitive validation
       if(!isInt($user->age)){
           //log the invalid input error
           return "age"; 
       }
       if(!isString($user->name)){
           //log the invalid input error
           return "name";
       }
       //business logic validation

        //our buisnees only accept grown peoples
        if($user->age < 18){
            //log the error
            return "age";
        }
        //our buisness accepts only users with good physique
        if($user->weight > 100){
            //log the error
            return "weight";
        }
        //ervery thing is ok ? then insert the user
        //data base query (insert into user (,,,) valeues (?,?,?,?))
        return true;
}

Теперь задача контроллера / ов состоит в том, чтобы «использовать» функцию модели registerUser() без знания того, как модель будет выполнять валидацию, или даже того, что считается «действительным» или нет!

Контроллер:

$user = new User();
$user->age = isset($_POST['age']) ?  $_POST['age'] : null;
$user->name = isset($_POST['name']) ?  $_POST['name'] : null;
$user->age = isset($_POST['weight']) ?  $_POST['weight'] : null;
$result = $theModel->registerUser($user);// <- the controller uses the model
if($result === true){
//build the view(page/template) with success message and die
}
$msg = "";
//use the return value from the function or you can check the error logs
switch ($result){
    case"age" :
        $msg = "Sorry, you must be over 18";
        break;
    case "name":
        $msg = "name field is not correct";
        break;
    case "weight":
        $msg = "Sorry, you must have a good physique";
        break;
}
//build the view(page/template) with error messages and die

Класс пользователя

class User { 
    public $age;
    public $name;
    public $weight;
}

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

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

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

0 голосов
/ 15 января 2010

Предполагается, что ваше приложение структурировано как:

  • Model-View-Controller
  • Услуги
  • Настойчивость
  • Модель

Пользовательский ввод поступит на ваш контроллер, и вы будете использовать сервисы на уровне сервисов для его проверки.

0 голосов
/ 15 января 2010

Внутри контроллера у вас есть свойство ModelState, к которому вы можете добавить ошибки проверки.

См. этот пример на MSDN .

0 голосов
/ 15 января 2010
Business Logic  -> Controller
Data Validation -> Model
0 голосов
/ 15 января 2010

Его бизнес-логика, так что нет, он не принадлежит модели.

...