输入验证在哪里属于MVC应用程序?

时间:2010-01-15 00:33:31

标签: model-view-controller language-agnostic model controller

我有一个MVC应用程序,它接收来自表单的输入 这是一个登录表单,因此唯一需要的验证是检查输入是否为非空 在我将它传递给模型之前,我在控制器中验证它 这是最佳做法吗?它属于模型吗?

7 个答案:

答案 0 :(得分:13)

我认为没有官方的最佳做法限制对MVC模式的任何单个部分的验证。例如,您的视图可以(并且应该)使用Javascript进行一些前期验证。您的控制器还应提供相同类型的验证,以及更多与业务逻辑相关的验证。该模型还可以提供验证形式,即不允许空值的设置器。

对此at joelonsoftware进行了有趣的讨论。

答案 1 :(得分:6)

我一直在考虑这个问题并且在尝试在控制器和模型中进行验证之后......最后我得出的结论是,对于我的许多应用程序来说......验证属于模型而不是在控制器中。为什么?因为相同的模型将来可以被各种其他控制器调用或API使用......然后我将不得不一遍又一遍地重复验证过程。这会违反DRY并导致许多错误。另外,哲学上它是与数据库(或其他持久性存储)交互的模型,因此无论如何都是“最后调用酒精”的地方。

所以我在控制器中进行get / post转换,然后将原始数据发送到模型进行验证和处理。当然我经常做php / mysql web应用程序,如果你正在做其他事情,结果可能会有所不同。我希望这有助于某人。

答案 2 :(得分:1)

验证必须在模型中

只有模特知道"细节"的业务。只有模型知道哪些数据是可接受的,哪些数据不是。控制器只知道如何使用"模特。

例如:让我们说我们需要向系统注册新用户的功能。

模特:

 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;
}

现在控制器的工作是&#34;使用&#34;模型registerUser()函数不知道模型将如何进行验证,甚至不考虑被认为是什么&#34;有效&#34;不是!

控制器:

$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;
}

拥有这样的架构将会免费提供#34;控制器完全来自业务逻辑的细节 - 这是一件好事 - 。

假设我们想在网站的其他地方进行另一种形式的用户注册(我们将为其分配另一个控制器)。现在另一个控制器将使用模型registerUser()的相同方法。

但是如果我们在控制器和模型之间分配验证逻辑,它们就不会分开 - 这对于MVC来说是坏的 - 这意味着每次你需要创建新视图和控制器来注册新用户时你必须使用相同的老控制器和模型在一起。此外,如果业务逻辑发生变化(我们现在接受我们体育俱乐部的青少年),您只需更改模型registerUser()功能中的代码。控制器代码仍然相同。

答案 3 :(得分:0)

它的业务逻辑,所以不,它不属于模型。

答案 4 :(得分:0)

在控制器中,您可以使用ModelState属性向其添加验证错误。

请参阅this example on the MSDN

答案 5 :(得分:0)

假设您的应用程序结构如下:

  • 模型 - 视图 - 控制器
  • 服务
  • 持久性
  • 模型

用户输入将来到您的控制器,您将使用服务层中的服务来验证它。

答案 6 :(得分:-3)

Business Logic  -> Controller
Data Validation -> Model