2

假设我有一个这样的域模型:

public class MyDomainEntity
{
    public double SomeVar { get; set; }
}

我有一个视图,我想将 SomeVar 显示为百分比。所以我的视图模型看起来像:

public class MyViewEntity
{
    public double SomeVarAsPercentage { get; set; }
}

我有一个映射类,它在视图模型和域模型之间进行映射,它简单地将变量除以 100。

现在我想对域模型进行一些验证。在这种情况下,业务规则规定域模型中的 SomeVar 必须介于 0.0 和 1.0 之间(含)。这很容易通过 System.ComponentModel.DataAnnotations.RangeAttribute 完成:

public class MyDomainEntity
{
    [Range(0.0, 1,0)]
    public double SomeVar { get; set; }
}

我可以使用

MyDomainEntity r = new MyDomainEntity();

...
//mapping code from view-model to domain model
...

IList<ValidationResult> results = new List<ValidationResult>();
ValidationContext context = new ValidationContext(r, null, null);
Validator.TryValidateObject(r, context, results, true);
foreach (ValidationResult e in results)
{
    //I would like to display the error messages, if any, to the user
}

但是,由于验证是在域模型中完成的,因此错误消息如下所示:

"The field SomeVar must be between 0 and 1"

而上面的错误信息需要翻译成视图模型才能阅读:

"The field SomeVarAsPercentage must be between 0 and 100"

为了对用户有意义。

这里的问题是:

  1. DataAnnotations 是否有能力进行这种“错误消息翻译”?
  2. 在这种情况下,我不应该在域模型中进行验证吗?
  3. 也许 DataAnnotations 作为一种验证机制在这里是不够的或不合适的?如果是这种情况,请建议一些其他框架

更新:

我对这个问题想了更多,似乎有几种方法

方法 1:视图模型中的验证

将验证移至视图模型,如下所示:

public class MyViewEntity
{
    [Range(0.0, 100.0)]
    public double SomeVarAsPercentage { get; set; }
}

因此 DataAnnotations 可以生成所需的错误消息。

然而,在视图模型中进行验证(与在域模型中相对)更WET。假设我的表单可以在两种视图之间切换:一种是 SomeVar 显示为百分比,另一种是 SomeVar 显示为“原样”,但只显示小数点后两位。然后我必须这样做:

public class MyViewEntity1
{
    [Range(0.0, 100.0)]
    public double SomeVarAsPercentage { get; set; }
}


public class MyViewEntity2
{
    [Range(0.0, 1.0)]
    public double SomeVarToTwoDp { get; set; }
}

我必须将 Range 规则放在两个地方,但两者实际上是相同的规则。

优点:简单
缺点:有点湿

方法 2:在域模型中验证,稍微修改 validate 方法

扩展 DataAnnotations 验证框架,使其不仅返回错误属性名称,还返回它违反的规则和错误消息工厂。因此 View-Model 实体和 Domain Model 实体之间的映射将使用错误消息工厂和规则(也需要映射)生成有意义的错误消息。

优点:更 DRY,验证规则在域模型中只出现一次
缺点:更复杂

4

1 回答 1

1

我想说你应该在两个地方都进行验证——ViewModel 中的 SomeVarAsPercentage,适当地显示你的 ViewModel 验证错误消息,并丢弃无效的输入(即不要将它们传递给模型)。

然后,在您的模型中,您可以验证 SomeVar(如果它通过了 VM 验证阶段)。该模型可以向 VM 报告错误(以其术语),VM 可以将它们转换为用户域术语,就像 VM 对值所做的那样。

您需要在这两个地方进行验证,因为验证类型不同 - 在 VM 中进行简单的百分比验证,但可能在模型中进行更复杂的验证,同时考虑其他值等。

于 2012-09-19T07:38:46.933 回答