假设我有一个这样的域模型:
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:在View-Model中验证
将验证移至视图模型,如下所示:
public class MyViewEntity
{
[Range(0.0, 100.0)]
public double SomeVarAsPercentage { get; set; }
}
因此DataAnnotations可以生成所需的错误消息。
然而,在视图模型中进行验证(与域模型中相同)更为谨慎。假设我的表单可以在两个视图之间切换:一个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规则放在两个地方,但两者都是相同的规则。
优点:简单
缺点:有点WET
方法2:在域模型中验证,使用稍微修改的验证方法
扩展DataAnnotations验证框架,使其不仅返回错误属性名称,还返回它违反的规则和错误消息工厂。因此,View-Model实体和Domain Model实体之间的映射将使用错误消息工厂和规则(也需要映射)生成有意义的错误消息。
优势:更多DRY,验证规则仅在域模型中出现一次
缺点:更复杂
答案 0 :(得分:1)
我想说你应该在两个地方进行验证 - ViewModel中的SomeVarAsPercentage,根据需要显示你的ViewModel验证错误信息,并丢弃无效输入(即不要将它们传递给模型)。
然后,在您的模型中,您可以验证SomeVar是否通过VM验证阶段。该模型可以向VM报告错误(以其术语表示),VM可以将它们转换为用户域术语,就像VM对值所做的那样。
您需要在两个地方进行验证,因为验证类型不同 - 在VM中进行简单的百分比验证,但可能在模型中进行更复杂的验证,同时考虑其他值等。