[英]MVC 3 Model Validation Issue - Oversight or By Design
我遇到了一個場景,我需要知道當前在自定義ValidationAttribute
驗證了哪個屬性 。 我認為這在MVC 3中很容易,因為ValidationContext
被傳遞給IsValid
方法。
沒有詳細說明,這是基本的想法:
protected override ValidationResult IsValid(Object value, ValidationContext validationContext) {
if (ShouldICareAboutYou(validationContext.MemberName))
{
//Do some stuff
}
//Return the results
}
這似乎是完美的解決方案,事實上,當使用Validator.TryValidateObject
對我的自定義ValidationAttribute進行單元測試時,一切都運行得非常好!
然而...
在我的控制器中調用TryUpdateModel
或TryValidateModel
,驗證會運行,但ValidationContext.MemberName
為null。
哇啊?!?
我做了一點調查,果然,在DataAnnotationsModelValidator
里面就是代碼......或者沒有代碼。
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
應用於屬性, DisplayName
可以是屬性名稱。 不幸的是,我無法真正處理假設。 我需要確切知道屬性名稱是什么。
那么這筆交易是什么? 這是設計還是誠實的疏忽。 如果它是一個疏忽,那么在MVC 4中修復它會很棒:)
上面的代碼示例中添加的注釋意味着很有趣。 我不知道,也沒見過Phil Haack 。 從我所知,他似乎是一個非常好的人。 在中學推他下去會讓我成為一個皇室沖洗!
我有同樣的問題,並決定將屬性名稱作為參數傳遞給屬性構造函數,然后將其存儲在屬性中。 例如:
[MyValidationAttribute("MyProperty")]
public string MyProperty { get; set; }
然后在MyValidationAttribute.cs中:
public class MyValidationAttribute
{
private string PropertyName;
public MyValidationAttribute(string propertyName)
{
this.PropertyName = propertyName;
}
}
這有點煩人,現在我必須兩次輸入我的屬性的名稱,但它解決了問題。
喬希,
令人沮喪,是的。
但是,出於您的目的,您可以創建自己的繼承自DataAnnotationsModelValidator
的類,重寫Validate()
方法,並取消注釋那些嘲弄您的代碼行。 然后,在Global.asax.cs中,清除ModelValidatorProviders.Providers
並添加您的類。
這不是一個最佳解決方案,而是一個可以幫助您到達目的地的解決方案。
您需要為屬性類型調用DataAnnotationsModelValidatorProvider.RegisterAdapter
或DataAnnotationsModelValidatorProvider.RegisterAdapterFactory
方法並提供自定義ModelValidator
。
有同樣的問題,這個問題讓我走上正軌。 我通過更改自定義驗證器來修復它,以便在創建ValidationResult時填充MemberName,如下所示(請注意ValidationResult構造函數中的第二個參數):
protected override ValidationResult IsValid(Object value, ValidationContext validationContext) {
if (ShouldICareAboutYou(validationContext.MemberName))
{
//Do some stuff
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new string[] { validationContext.MemberName });
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.