【发布时间】:2011-01-05 08:00:06
【问题描述】:
我有一个从表单接收输入的 MVC 应用程序。
这是一个登录表单,因此唯一需要的验证是检查输入是否为非空。
现在,在我将它传递给模型之前,我在控制器中对其进行验证。
这是否是最佳实践?是否属于模型?
【问题讨论】:
标签: model-view-controller language-agnostic model controller
我有一个从表单接收输入的 MVC 应用程序。
这是一个登录表单,因此唯一需要的验证是检查输入是否为非空。
现在,在我将它传递给模型之前,我在控制器中对其进行验证。
这是否是最佳实践?是否属于模型?
【问题讨论】:
标签: model-view-controller language-agnostic model controller
我认为没有官方的最佳实践将验证限制在 MVC 模式的任何单个部分。例如,您的视图可以(并且应该)使用 Javascript 进行一些预先验证。您的控制器还应该提供相同类型的验证,以及更多与业务逻辑相关的验证。该模型还可以提供验证形式,即不允许空值的设置器。
有一个关于这个at joelonsoftware的有趣讨论。
【讨论】:
我一直在考虑这个问题并尝试在控制器和模型中进行验证之后......最后我得出的结论是,对于我的许多应用程序......验证属于模型而不是在控制器中。为什么?因为相同的模型将来可能被各种其他控制器调用或 API 使用......然后我将不得不一遍又一遍地重复验证过程。这将违反 DRY 并导致许多错误。再加上哲学上它与数据库(或其他持久存储)交互的模型,因此无论如何都是“最后一次喝酒”的地方。
所以我在控制器中进行 get/post 转换,然后将原始数据发送到模型进行验证和处理。当然,我经常做 php/mysql web 应用程序,如果你在做其他事情,结果可能会有所不同。我希望这对某人有所帮助。
【讨论】:
验证必须在模型中
只有模型知道业务的“细节”。只有模型知道哪些数据可以接受,哪些数据不能接受。控制器只知道如何“使用”模型。
例如:假设我们需要向我们的系统注册新用户的功能。
模型:
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() 函数中的代码。控制器代码还是一样的。
【讨论】:
它的业务逻辑,所以不,它不属于模型。
【讨论】:
在控制器中,您有 ModelState 属性,您可以向其中添加验证错误。
【讨论】:
假设您的应用程序结构如下:
用户输入将到达您的控制器,您将使用服务层中的服务来验证它。
【讨论】:
Business Logic -> Controller
Data Validation -> Model
【讨论】: