我有映射到ViewModels的DTO。为了避免必须管理验证属性(和其他属性),我想为单个类的所有属性编写验证属性,并在我的ViewModel上重用它。但是,当我尝试在没有DTO所有属性的ViewModel上使用元数据时(所有这些都属于......),它给了我一个System.InvalidOperationException
例外。
例外:
Le type de métadonnées associé pour le type 'MyProject.EntityViewModel' contient les propriétés ou champs inconnus suivants : AnotherProperty. Vérifiez que les noms de ces membres correspondent aux noms des propriétés du type principal.
谷歌翻译:
The type associated metadata for type 'MyProject.EntityViewModel' contains the following unknown properties or fields: AnotherProperty. Verify that the names of these members match the names of the properties of the main type.
简化示例:
public class Entity {
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
public class EntityDTO {
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
//This class is used to add validation attributes for input-related view models
public class EntityInputValidation {
[Required]
public string A { get; set; }
[Required]
public string B { get; set; }
//Notice that we dont have a validation for C
}
//This class is a ViewModel used to create a new Entity
[MetadataType(typeof(EntityInputValidation))]
public class EntityCreateViewModel {
//Required because we use the InputValidation metadata
public string A { get; set; }
//Notice that we do not have the B property here, even if we are using the Input Validation which has a required attribute for this property. This is where the exception comes from.
//C is only required in this View/ViewModel
[Required]
public string C { get; set; }
}
因为EntityViewModel没有AnotherProperty
,所以会抛出异常。有办法防止这种情况吗?
答案 0 :(得分:2)
我当然会重新考虑在您的实体上直接使用这些注释。正如您已经看到的那样,只要您需要在不需要遵守这些验证规则的视图中使用该实体,就会出现问题。如果添加更多使用您实体的视图,那么从长远来看,这可能会变得更糟。
无论你提出什么解决方案来阻止抛出异常都将是一个黑客攻击。
每条评论更新
每当我们需要更改验证规则时,我都不想搜索20个视图模型......我们目前有2个网站,很快就会有3个网站,它们是使用相同DAL和业务逻辑的解决方案的一部分。这是很多视图模型,以保持更新。
这当然是一个有效的问题,这也是一个有效的问题。问题更多的是没有明确定义的解决方案,至少我已经找到了。
看一下继承思想,一开始看似合理。但是,如果您的属性适合整齐的组,这只会起作用,从您更新的问题看来可能不是这样。
我们举一个简单的例子:
public class LoginValidation
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
然后,您可以从中获取视图模型:
public class ViewModelA : LoginValidation
{
public string SomeOtherProperty { get; set; }
}
然而,这带来了一个问题。如果要继承另一组验证属性,该怎么办?你不能,因为我们被限制从一个类继承。我们也无法从接口继承数据注释:
产品团队不希望实现此功能,原因有两个:
- 与DataAnnotations.Validator的一致性
- 醇>
与ASP.Net MVC中的验证行为保持一致
棘手的场景:一个类实现了两个具有相同属性但具有相互冲突属性的接口。哪个属性优先?
那么如果您需要LoginValidation
并对某个特定视图进行某些日期验证呢?您必须在中间类中创建一个继承链,只是为了能够继承视图模型的继承链:
public class LoginAndDateValidation : LoginValidation
{
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime EndDate { get; set; }
}
public class ViewModelA : LoginAndDateValidation
{
public string SomeOtherProperty { get; set; }
}
你知道这是怎么回事吗?这将变成一个完整的混乱。因此,正如我之前所说,只有当您的属性适合并且在明确定义的组中使用时,这才会起作用,但在您的方案中似乎不是这样。
要完成,请让我链接到Mystere Man几年前发布的答案,我一直很喜欢:https://stackoverflow.com/a/8075115/729541