hom*_*ata 5 validation asp.net-mvc
相关: 使用ASP.NET MVC实现字段验证的最佳方法是什么?
让我们假设一个具有以下项目的解决方案:
Foo; // the MVC web project
Foo.Models;
Foo.Repositories;
Foo.Services;
Run Code Online (Sandbox Code Playgroud)
Foo.Models是所有实体的应用程序域,无论使用EF,NH,POCO还是其他什么都无关紧要.这是一个例子:
public class User
{
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在Foo.Repositories那里有一个,UserRepository并且Foo.Services有一个UserService.
在Web应用程序中,让我们考虑如下的模型绑定器:
public class UserBinder : DefaultModelBinder
{
//...
}
Run Code Online (Sandbox Code Playgroud)
我在验证的位置上看到了三种不同的选项:
在Foo.Models像下面这样:
public class User
{
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public ICollection<KeyValuePair<string, string>> ValidateErrors()
{
//Validate if Username, Email and Password has been passed
}
}
Run Code Online (Sandbox Code Playgroud)在Foo.Services:像:
public class UserService
{
public ICollection<KeyValuePair<string, string>> ValidateErrors()
{
//Validate if Username, Email and Password has been passed
}
}
Run Code Online (Sandbox Code Playgroud)在Foo模型绑定器内部:
public class UserBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var user = (User)bindingContext.Model;
// validate everything here
base.OnModelUpdated(controllerContext, bindingContext);
}
}
Run Code Online (Sandbox Code Playgroud)另外需要注意的是,考虑前两个选项[模型和服务],还有另一个决定:ValidateErrors方法可以直接在控制器上或在Binder内部调用.
我对这个场景有2个问题:
验证应该是:
以上所有场景都讨论了用户创建.但是用户登录呢?假设用户使用用户名和密码登录应用程序,因此不需要验证电子邮件.这个验证应该在哪里?
经过大量研究后,我想我得到了问题的答案,所以我决定分享。
验证码应该在模型上。根据“瘦控制器,胖模型”的想法,并考虑到模型会知道它需要验证什么或不需要验证什么。
例如,假设我决定Foo.Models在其他解决方案中使用,但我决定不使用任何其他项目,并且验证在其他项目中进行。在这种情况下,我必须重新编码整个验证,这完全是浪费时间,对吗?
好的。验证代码必须在模型中,但是应该在哪里调用呢?
必须在将其保存到数据库或文件时调用此验证。正如在建议的场景中,我将存储库视为一个域,那么我们应该考虑在保存更改之前进行验证[在本示例中,我使用实体框架,但这不是必需的,只是为了显示]:
public class UserRepository : IRepository<User>
{
public void Create(User user)
{
user.Validate();
var db = dbFooEntities();
db.AddToUsers(user);
db.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
根据 MS 的建议,模型验证应该引发异常,并且控制器必须使用发现的错误填充 ModelState [一旦完成我的应用程序,我将尝试使用示例代码更新此答案]。
这样我们就有了问题#1 的答案。
关于登录验证的问题#2 怎么样?
由于登录不是持久保存数据的情况,因此验证应保留在服务上,因为在这种情况下登录是一项服务。
所以,问题的答案是:
在从存储库调用的模型中[由控制器调用]
在从控制器调用的服务中
| 归档时间: |
|
| 查看次数: |
2060 次 |
| 最近记录: |