建议验证的地方是什么:ViewModel,Model或Controller?

时间:2011-03-02 04:06:47

标签: asp.net-mvc asp.net-mvc-2-validation

我有一个注册页面,并希望对重复的用户名和电子邮件地址执行一些验证(除了我的ViewModel上的StringLength和Required annotations)。目前,我在回收注册表单时在我的控制器中执行此验证。我不确定这是否适合这样做。

我无法想象ViewModel是正确的位置,因为它需要ViewModel来引用我的UserRepository。在模型类中进行这种验证是否有意义?

如果是这样,我如何在模型上实现这一点,以便在将信息发送到我的存储库之前检查信息是否有效?

更新

我的控制器操作代码:

if (ModelState.IsValid)
        {
            if (!_userRepository.Exists(registerViewModel.Username))
            {
                if (!_userRepository.EmailExists(registerViewModel.Email))
                {
                    _userRepository.Add(
                        new User
                            {
                                Created = DateTime.Now, 
                                Email = registerViewModel.Email, 
                                Password = registerViewModel.Password, 
                                Username = registerViewModel.Username
                            });

                    _userRepository.SaveChanges();
                    TempData["registrationDetails"] = registerViewModel;

                    return RedirectToAction("Confirm");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "This email address is already in use.");
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "This username is already taken.");
            }
        }

        return View(registerViewModel);
    }

更新2

域模型是否应该关注重复用户名或电子邮件地址等约束,或者这是控制器层应该担心的问题?

更新3

似乎将验证逻辑放在控制器中是最有意义的,因为它可以在远程验证和提交模型验证中重用。检查重复项通常是应该在控制器中完成的事情,还是在域模型中进行这类检查是否有意义?

谢谢,

5 个答案:

答案 0 :(得分:1)

我会在前端(也许是ajax)和后端执行它 - 这取决于你的解决方案架构。

我想让用户立即知道是否会出现注册问题。 在我对数据层/业务层和表示层的典型设置中,我将在业务逻辑中执行重复检查,并让控制器调用该段代码(除了前端的ajax查找用户)。 / p>

作为一个侧面说明:我通常更喜欢在Windows应用程序中仅使用MVVM(带有视图模型)。将MVC与MVVM结合起来会使事情变得不必要地复杂化

答案 1 :(得分:0)

Rob在评论中说,这取决于你的应用程序的结构。我倾向于进行双重验证(在我的ViewModel上进行验证以及在我的服务层上进行验证)以确保获得服务的数据有效。这有帮助,因为我的服务被多个客户端使用,但视图和ViewModel是特定于客户端的。前端验证具有即时反馈的优势,后端验证有助于保持数据清洁。

答案 2 :(得分:0)

我的建议是 - 用于验证,例如重复的电子邮件地址和用户名 - 以将您的验证方法保留在控制器中。

或者在验证层中 - 将在视图模型和数据层之间使用

对于MVC3,您将能够在控制器中添加方法作为对视图模型中的属性使用Remote属性的操作以获得即时结果

答案 3 :(得分:0)

我建议您在控制器中执行此操作。

主要原因是无论应用程序的结构如何,您肯定需要使用Ajax来通知用户是否已经使用了用户名。否则,它只是糟糕的可用性,这不能证明你的代码结构。

为此,您希望有一个动作方法,可以查看用户名是否存在。

总的来说,它确实意味着你最终可能会得到两套验证方法(UI和模型),但这一切都是有充分理由的。

另外,为了建立一个好的可用站点,你肯定会使用像knockoutjs或backbone这样的Javascript框架。这是真正的MVVM,在这种情况下,将ViewModel作为Model层类(正如Chris所提到的)并不是一个好主意。所以基本上你最终会得到两套验证。

答案 4 :(得分:0)

您应该在View(客户端)和Controller(服务器端)中进行验证。如果您有MVC 3,则可以使用新的RemoteAttribute。它使用jQuery进行服务器端调用,您可以在其中检查是否存在用户或电子邮件地址。