簡體   English   中英

MVC 3模型驗證問題 - 監督或設計

[英]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進行單元測試時,一切都運行得非常好!

然而...

在我的控制器中調用TryUpdateModelTryValidateModel ,驗證會運行,但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.RegisterAdapterDataAnnotationsModelValidatorProvider.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM