假设我有一个这样的域模型:
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"
为了对用户有意义。
这里的问题是:
- DataAnnotations 是否有能力进行这种“错误消息翻译”?
- 在这种情况下,我不应该在域模型中进行验证吗?
- 也许 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,验证规则在域模型中只出现一次
缺点:更复杂