0

在使用 FluentValidation 时,我有一个单独的.dll,其中包含我们的数据库模型和部分类等,它工作正常(桌面条形码终端和我们的网站都可以使用它)。

对于桌面应用程序,我可以读取并显示所有错误,如下所示

public override int SaveChanges()
    {
        var errors = this.GetValidationErrors();
        if (errors.Any())
        {
            //handle validation errors
            return 0;
        }
        else
        {
            return base.SaveChanges();
        }
    }

对于 MVC 站点,我可以在单个模型上设置验证器或创建数据注释并让它们正常工作(这不是我想要的)。我无法理解的是如何强制我的模型映射到我的实体,以便我可以在视图中显示流畅的验证消息。我不想维护两组单独的逻辑,并且条形码应用程序和网站必须使用相同的逻辑。

我必须将我的实体直接映射到视图吗?我一直认为这是一件坏事,而且不是很灵活。或者有没有办法说明模型中的字段映射回我的一个实体的属性?也许是一些描述的注释。

编辑:

只是对我需要的验证类型进行一些说明。

大多数前端输入类型验证仍将保留在 viewModels 中(必需/长度/密码匹配等 - 基本上我也可以用于客户端验证的所有内容)。但是有所有我不想要的业务逻辑验证。必须在设置其他选项之前验证电子邮件地址之类的东西,帐号必须是基于名称的特定格式(我不能用正则表达式做的事情)。此特定日期不是有效的交货日期等。

我想我可以做的一件事是以某种方式将这些添加到 ValidationSummary 并将它们与各个字段分开显示。

4

2 回答 2

1

我认为你只是看错了情况。MVC 的全部内容是关注点分离。数据库需要知道您的视图可能不太关心的事情,反之亦然。这就是为什么推荐的做法是将视图模型与您的视图一起使用,而不是实体本身。

验证大致相同。密码确认需要与用户输入的密码相匹配这一事实与数据库完全无关。或者更恰当地说,诸如验证密码中的最小字符数之类的东西也与数据库无关;它只会收到密码的加盐和散列版本。因此,将这种验证放在您的实体上是错误的。它属于视图模型。

当我第一次开始使用 MVC 时,我曾经将所有验证逻辑添加到我的实体类中,然后在我的视图模型上重复相同的验证。随着时间的推移,我开始意识到实际上很少需要对两者进行验证。事实上,大多数验证应该只在您的视图模型上进行。它充当某种看门人;如果数据足以通过您的视图模型,那么对于您的数据库来说就足够了。对您的实体有意义的验证类型是这样的Required,但即使这样,也仅在必须在它到达您的数据库时有一个值。默认情况下,像 DateTimes 这样的东西是不可为空的,而 EF 足够聪明,可以使它们在默认创建的表上不可为空。MaxLength如果对数据库中文本字段的长度有硬性限制,有时是值得的,但通常情况下,nvarchars 工作得很好。

无论如何,关键是如果您真的坐下来开始评估实体上的验证,您可能会发现其中大部分是业务逻辑,仅适用于您的应用程序的工作方式,而不适用于数据在数据库中的表示方式等级。这是关键要点:在您的实体上,您只需要对数据库进行必要的验证。这通常很薄。

于 2013-04-04T19:14:40.500 回答
1

只是一个更新。为了获得我需要的两层验证,我必须将所有实体模型类标记为 IValidatable。然后我覆盖每个类的验证方法并在那里调用我的流利验证验证器方法,传回所需的错误。对于modelstate.addmodelerror,我将键设置为字段名,它映射回来没问题。更多的代码,但它的工作原理。如果我找到更好的方法来做这个病态的更新。

于 2013-04-08T17:00:33.533 回答