建议在哪里执行验证:ViewModel、模型还是控制器?
我有一个注册页面,想要对重复的用户名和电子邮件地址执行一些验证(除了 ViewModel 上的 StringLength 和必需注释之外)。目前,当注册表单回发时,我在控制器中执行此验证。我不确定这是否是正确的地方。
我无法想象 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
似乎将验证逻辑放入控制器中最有意义,因为它可以在远程验证和提交时的模型验证中重用。检查重复项之类的事情通常应该在控制器中完成,或者在域模型中进行此类检查是否有意义?
谢谢,
I have a registration page and would like to perform some validation (in addition to the StringLength and Required annotations on my ViewModel) for duplicate usernames and email addresses. Currently I perform this validation in my controller when the registration form is posted back. I'm not sure if this is the right place to do it though.
I can't imagine the ViewModel to be the right place as it would require the ViewModel to have a reference to my UserRepository. Does it make sense to have this kind of validation in the model classes?
If so, how do I implement this on the model so I can check if the information is valid before I sent it into my repository?
Update
Code of my controller action:
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);
}
Update 2
Should the domain model care about such constraints as duplicate user names or email addresses or is this something that the controller layer should worry about?
Update 3
It seems that putting the validation logic in the controller makes the most sense as it can be reused in remote validation and in model validation on submit. Is something like checking for duplicates generally a thing that should be done in controllers or does it make sense to have these kind of checks in a domain model?
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我会在前端(可能是ajax)和后端上执行它 - 这取决于您的解决方案架构。
如果出现注册问题,我希望立即让用户知道。
在数据层/业务层和表示层的典型设置中,我将在业务逻辑中执行重复检查,并让控制器调用该代码段(除了在前端为用户进行 ajax 查找之外)。
顺便说一句:我通常更喜欢在 Windows 应用程序中只使用 MVVM(带有视图模型)。将 MVC 与 MVVM 结合起来会使事情变得不必要的复杂
I would perform it both on the frontend (ajax perhaps) and backend - which depends on your solutions architecture.
I like to let users know immediately if there's going to be a registration issues.
In my typical setup of a data layer / business layer and presentation layer, I would perform the dup checks in the business logic and have the controller call that piece of code (in addition to an ajax lookup on the front end for users).
As a bit of a side note: I generally prefer to only use MVVM (with view models) in windows applications. Combining MVC with MVVM can make things unnecessarily complicated
我建议您在控制器中执行此操作。
主要原因是,无论应用程序的结构如何,您肯定需要使用 Ajax 来通知用户用户名是否已被占用。否则,这只是糟糕的可用性,无法证明您的代码结构合理。
为此,您希望有一个操作方法,可以通过ajax方式查看用户名是否存在。
总的来说,这确实意味着您最终可能会得到两套验证方法(UI 和模型),但这都是有充分理由的。
另外,为了制作一个良好的可用网站,您肯定会使用 Javascript 框架,例如 knockoutjs 或backbone。这就是真正的 MVVM,在这种情况下,将 ViewModel 作为模型层类(正如 Chris 提到的)并不是一个好主意。所以基本上你最终会得到两组验证。
I would suggest that you do this in Controllers.
The main reason is that whatever the structure of the app be, you would definitely need to use Ajax to notify the user whether the username has already been taken or not. Otherwise it's just bad usability which doesn't justify your code structure.
And for that you would like to have a action method which could ajax-ly see if the username exists or not.
Overall, it does mean you may end up with two sets of validation method (UI and model) but its all for a good cause.
Also to make a good usable site you would definitely be using a Javascript framework like knockoutjs or backbone. Thats true MVVM and in that case having your ViewModels being the Model layer classes (as Chris mentioned) is not a good idea. So basically you'll end up with two sets of validation anyways.
正如 Rob 在评论中所说,这确实取决于您的应用程序的结构。我倾向于进行双重验证(对我的 ViewModel 进行验证以及对我的服务层进行验证),以确保访问服务的数据有效。这很有帮助,因为我的服务被多个客户端使用,但视图和 ViewModel 是特定于客户端的。前端验证具有即时反馈的优势,后端验证有助于保持数据干净。
As Rob said in the comments, it does depend on the structure of your application. I tend to have a double validation (Validation on my ViewModels as well as validation on my service layer) to ensure that the data that hits the service is valid. This helps because my services get used by multiple clients, but the views and ViewModels are client specific. Front end validations have the advantage of instant feedback, and the backend validations help keep your data clean.
我的建议是 - 对于验证,例如重复的电子邮件地址和用户名 - 将验证方法保留在控制器中。
或者在您的验证层中 - 将在 MVC3 的视图模型和数据层之间使用,
您将能够使用 Remote 属性将控制器中的方法作为操作添加到视图模型中的属性以获得即时结果
My suggestion is - For validation, such as duplicate email address and user name- to keep your validation methods in controller.
Or in your Validation Layer - which will be used in between view model and data layer
for MVC3 you will be able to add methods in controller as a actions using Remote attribute to your property in view model for instant results
您应该在视图(客户端)和控制器(服务器端)中进行验证。如果您有 MVC 3,则可以使用新的 远程属性。它使用 jQuery 进行服务器端调用,您可以在其中检查用户或电子邮件地址是否存在。
You should validate in both the View (client-side) and Controller (server-side). If you have MVC 3, you can use the new RemoteAttribute. It uses jQuery to make a server-side call, in which you could check for the existence of a user or email address.