相同的 DataAnnotation 属性在同一属性上重复
我正在处理一些非常疯狂的自定义验证。基本上,根据下拉列表的选择,将确定针对目标属性验证哪些值。
例如,我有以下下拉列表:
1 = 汽车
2 = 卡车
在我的自定义验证中,如果选择是汽车,则该值不能超过 20。如果选择是卡车,则该值不能超过 40。
所以我的属性需要看起来像这样:
[ValueBelowIf("1", 20)]
[ValueBelowIf("2", 40)]
public int Value { get; set; }
当然,为了让它编译,我必须在我的自定义属性上设置它:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class ValueBelowIfAttribute : ValidationAttribute, IClientValidatable
但是,似乎只有第一个属性被绑定 - 第二个属性被忽略。
我做错了什么?
I have some pretty crazy custom validation I'm working on. Basically, based on the selection of a dropdown, that will determine what values are validated against the target property.
For example, I have the following dropdown:
1 = Car
2 = Truck
On my custom validation, if the selection is car, then the value can't be more than 20. If the selection is truck, the value can't be more than 40.
So my attributes need to look something like this:
[ValueBelowIf("1", 20)]
[ValueBelowIf("2", 40)]
public int Value { get; set; }
Of course, to even get it to compile, I have to set this on my custom attribute:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class ValueBelowIfAttribute : ValidationAttribute, IClientValidatable
However, it appears only the first attribute is being bound -- the second is ignored.
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要覆盖 类型ID。 MVC 的验证器将仅根据其 TypeId 值评估每个唯一属性。
将您的属性实现更改为以下内容,它将起作用:
根据我的收集,AllowMultiple(至少在 MVC 的情况下)只是告诉编译器该属性多次出现是有效的,但控制这些属性的方式是 TypeId属性在运行时评估。
这可能很有用,因为您可以静态地(在编译时)允许多次应用相同的属性类型,但在运行时忽略逻辑上重复的属性。例如,在我的示例中,我可以返回属性参数的哈希码,而不是返回保证唯一的 new object()。在这种情况下,如果您这样做:
将不会评估第二个
[ValueBelowIf("2", 40)]
。阅读更多详细信息,我在这里找到了答案:
http://www.paraesthesia.com/archive/2010/03/02/the-importance-of-typeid-in-asp.net-mvc-dataannotations-validation-attributes.aspx
You need to override the default implementation of TypeId. MVC's validator will only evaluate each unique attribute based on it's TypeId value.
Change your attribute implementation to the following, and it'll work:
From what I gather, AllowMultiple, at least in the case of MVC, just tells the compiler that the attribute is valid appearing multiple times, but it is TypeId that controls how those attributes are evaluated at runtime.
This can be useful because you can statically (at compile time) allow the same attribute type to be applied multiple times, but at runtime ignore logically duplicated attributes. For example, in my example instead of returning a guaranteed-unique new object(), I could return a hashcode of the attribute parameters. In that case, if you did:
the second
[ValueBelowIf("2", 40)]
would not be evaluated.Read more details where I came across the answer here:
http://www.paraesthesia.com/archive/2010/03/02/the-importance-of-typeid-in-asp.net-mvc-dataannotations-validation-attributes.aspx
您正在尝试将类范围的验证逻辑实现到属性验证技术中。不要那样做!使用适当的类验证机制,例如实现 IValidatableObject,或使用 FluentValidation
You are trying to implement class-wide validation logic into property-validation technique. Dont do that! Use proper class-validation mechanism instead, for example implement IValidatableObject, or use FluentValidation
由于 C# 属性是有限的常量,因此我发现实现此目的的最佳方法是通过构造函数将所有值作为单独的值提供。这很丑陋,但却是唯一可以做到的方法。
例如:
Since C# Attrbiutes are limited constants, I found the best way to accomplish this is to provide all values through the constructor as separate values. This is ugly, but the only way it can be done.
For example: