我遇到了一个场景,我需要知道哪个属性是目前正在定制 ValidationAttribute
验证。我以为这会很容易在MVC 3,因为 ValidationContext
被传递到的 的IsValid
的方法。
I ran into a scenario where I needed to know which property was currently being validated in a custom ValidationAttribute
. I assumed this would be easy in MVC 3 since the ValidationContext
is being passed into the IsValid
method.
没有进入细节,这里的基本思想是:
Without going into detail, here is the basic idea:
protected override ValidationResult IsValid(Object value, ValidationContext validationContext) {
if (ShouldICareAboutYou(validationContext.MemberName))
{
//Do some stuff
}
//Return the results
}
这似乎像是一个完美的解决方案,而事实上,在单元测试我的自定义ValidationAttribute使用Validator.TryValidateObject一切都一级棒!
This seemed like the perfect solution, and indeed, when unit testing my custom ValidationAttribute using Validator.TryValidateObject
everything worked beautifully!
但是...
在调用TryUpdateModel,或TryValidateModel在我的控制器,验证运行,但 ValidationContext.MemberName
为空。
Whaa咦?!?
我做了一个小调查,果然,就在那里里面DataAnnotationsModelValidator是code ...或缺乏。
I did a little investigation and sure enough, right there inside of DataAnnotationsModelValidator
is the code... or lack thereof.
public override IEnumerable<ModelValidationResult> Validate(object container) {
// Per the WCF RIA Services team, instance can never be null (if you have
// no parent, you pass yourself for the "instance" parameter).
ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null);
context.DisplayName = Metadata.GetDisplayName();
// Setting the MemberName here would be trivial!
// However, philh told me not to. Something about
// a guy named Josh who pushed him down on the playground
// in middle school.
//context.MemberName = Metadata.PropertyName; (Suck It, Josh!!!)
ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);
if (result != ValidationResult.Success) {
yield return new ModelValidationResult {
Message = result.ErrorMessage
};
}
}
我知道显示名称
的可以的是属性名,如果没有 DisplayAttribute
已施加到属性。不幸的是我真的不能买卖hypotheticals。我需要知道的完全什么是属性名称是。
I realize that DisplayName
could be the property name if no DisplayAttribute
has been applied to the property. Unfortunately I can't really deal in hypotheticals. I need to know exactly what the property name is.
那么,什么是交易?这是由设计或一个诚实的监督如果这是一个疏忽,那么这将是真棒得到这个固定的MVC 4:。)
So what is the deal? Is this by design or an honest oversight. If it is an oversight, then it would be awesome to get this fixed in MVC 4 :)
在加入的的code样品上方意在评论很好玩。我不知道,我也没有见过菲尔哈克。从我可以告诉他似乎是一个真正的好人。而把他倒在初中就已经让我皇室冲洗!
The added comments in the code sample above are meant to be funny. I do not know, nor have I ever met Phil Haack. From what I can tell he seems like a really nice guy. And pushing him down in middle school would have made me a royal douche!
我有同样的问题,并决定在属性名传递作为属性构造函数的参数,然后将其存储在属性。例如:
I had this same problem and decided to pass in the property name as a parameter in the attribute constructor and then store it in the attribute. For example:
[MyValidationAttribute("MyProperty")]
public string MyProperty { get; set; }
然后在MyValidationAttribute.cs:
Then in MyValidationAttribute.cs:
public class MyValidationAttribute
{
private string PropertyName;
public MyValidationAttribute(string propertyName)
{
this.PropertyName = propertyName;
}
}
这是一个有点讨厌,现在我必须键入我的财产的名字两次,但它解决了这个问题。
It is a little annoying that now I have to type the name of my property twice but it solves the problem.