我有一个单独的.dll与我们的数据库模型和部分类等使用FluentValidation工作正常(它由桌面条形码终端和我们的网站使用)。
对于桌面应用程序,我可以阅读并显示所有错误,如下所示
public override int SaveChanges()
{
var errors = this.GetValidationErrors();
if (errors.Any())
{
//handle validation errors
return 0;
}
else
{
return base.SaveChanges();
}
}
对于MVC网站,我可以在单个模型上设置验证器或创建数据注释,并使那些工作正常(这不是我想要的)。我无法理解的是我如何强制我的模型映射到我的实体,以便我可以在视图中显示流畅的验证消息。我不想要维护两组独立的逻辑,条形码应用和网站必须使用相同的。
我是否必须将我的实体直接映射到视图?我被引导相信是一件坏事而且不是很灵活。或者有没有办法说明模型中的字段映射回我的某个实体的属性?也许是一些描述的注释。
编辑:
对我需要的验证类型进行一些澄清。
大多数前端输入类型验证仍将保留在viewModels中(必需/长度/密码匹配等 - 基本上所有我可用于客户端验证的东西)。但是有一些我不想要的业务逻辑验证。在设置其他选项之前必须验证电子邮件地址之类的内容,帐号必须是基于名称的特定格式(我不能用正则表达式做的事情)。此特定日期不是有效的交货日期等。
我想我能做的一件事就是将它们以某种方式添加到ValidationSummary中,并将它们与各个字段分开显示。
答案 0 :(得分:1)
我认为你只是看错了。 MVC的全部意义在于关注点的分离。数据库需要了解您的观点可能更少关注的内容,反之亦然。这就是为什么推荐的做法是将视图模型与您的视图一起使用而不是实体本身。
验证大致相同。类似于密码确认需要与用户输入的密码匹配的事实根本不涉及数据库。或者更恰当的是,密码中最小字符数量的验证也与数据库无关;它只会收到密码和哈希版本的密码。因此,对您的实体进行此类验证是错误的。它属于视图模型。
当我第一次开始使用MVC时,我曾经将所有验证逻辑添加到我的实体类中,然后在我的视图模型上重复相同的验证。随着时间的推移,我开始意识到实际上需要的验证很少。事实上,绝大多数验证都应该放在你的视图模型上。它充当各种看门人;如果数据足以通过您的视图模型,那么它对您的数据库来说已经足够了。在您的实体上有意义的验证类型是Required
之类的东西,但即使这只是在可以为空的字段上,必须在到达数据库时具有值。默认情况下,DateTimes之类的东西是不可为空的,并且EF足够聪明,可以在默认情况下创建的表上使它们不可为空。如果对数据库中的文本字段的长度存在严格限制,MaxLength
有时是值得的,但通常情况下,nvarchars工作得很好。
无论如何,如果你真的坐下来开始评估你的实体的验证,你可能会发现大多数业务逻辑只适用于你的应用程序如何工作而不如何在数据库级别表示数据。这是关键的一点:在您的实体上,您只需要对数据库进行必要的验证。而这通常很薄。
答案 1 :(得分:1)
只是一个更新。获得我需要的两层验证我必须将所有实体模型类标记为IValidatable。然后我覆盖每个类的validate方法,并在那里调用我的流畅验证验证器方法,传回所需的错误。对于modelstate.addmodelerror,我将密钥设置为字段名称,并将其映射回来。更多的代码,但它的工作原理。如果我找到更好的方法来做这个不好的更新。