2011-06-27 16 views
14

私はいくつかのポストを読んだが、MVC 3では、バリデーターを作成するのに実際には必要ではなく、属性のみを見つけることができませんでした。これは本当ですか?私は、属性がIClientValidatableを持っているのは混乱していると言います。 DataAnnotationsModelValidatorクラスは、注釈にクライアントサイドスクリプト名(IClientValidatable)と検証機能(ValidationAttribute IsValid)がある場合、何を行いますか?MVC 2 vs MVC 3 DataAnnotationsModelValidatorProvider.RegisterAdapterを使用したカスタム検証属性

私がしなかったのは、グローバルでバリデーターに属性を登録しなければならないと本当にいいですね。これはできますか?私は悪いアドバイスを読んだことがありますか?

EDIT:興味深いことに、私はバリデーターを除外してテストしました。すべてのロジックをIsValidに入れてください。欠けているかもしれない唯一のものはコントローラーのコンテキストだろうと思うが、それがバリデーションに役立つかどうかはわからない。 IsValidには、サービスが必要な場合にServiceContainerを持つValidationContextがあります。私がここでピックアップしていない本当の不利益は何ですか?

EDIT 2: 私はこの例からバリで始まりますhttp://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx

属性:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private RequiredAttribute innerAttribute = new RequiredAttribute(); 
    public string DependentProperty { get; set; } 
    public object TargetValue { get; set; } 

    public RequiredIfAttribute(string dependentProperty, object targetValue) 
    { 
     this.DependentProperty = dependentProperty; 
     this.TargetValue = targetValue; 
    } 

    public override bool IsValid(object value) 
    { 
     return innerAttribute.IsValid(value); 
    } 

    public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "requiredifattribute" 
     }; 
     modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty); 
     yield return modelClientValidationRule; 
    } 
} 

バリ:上記の現在のコードで

public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute> 
{ 
    public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     return base.GetClientValidationRules(); 
    } 

    public override IEnumerable<ModelValidationResult> Validate(object container) 
    { 
     var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty); 
     if (field != null) 
     { 
      var value = field.GetValue(container, null); 
      if ((value == null && Attribute.TargetValue == null) || 
       (value.Equals(Attribute.TargetValue))) 
      { 
       if (!Attribute.IsValid(Metadata.Model)) 
        yield return new ModelValidationResult { Message = ErrorMessage }; 
      } 
     } 
    } 
} 

、IはGlobal.asax.csファイルに登録する必要があります。

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute), typeof(RequiredIfValidator)); 

しかし、私はちょうど属性にすべてを移動した場合、私はそれを登録するには持っていけない:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private RequiredAttribute innerAttribute = new RequiredAttribute(); 
    public string DependentProperty { get; set; } 
    public object TargetValue { get; set; } 

    public RequiredIfAttribute(string dependentProperty, object targetValue) 
    { 
     this.DependentProperty = dependentProperty; 
     this.TargetValue = targetValue; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty); 
     if (field != null) 
     { 
      var dependentValue = field.GetValue(validationContext.ObjectInstance, null); 
      if ((dependentValue == null && TargetValue == null) || 
       (dependentValue.Equals(TargetValue))) 
      { 
       if (!innerAttribute.IsValid(value)) 
        return new ValidationResult(ErrorMessage); 
      } 
     } 
     return ValidationResult.Success; 
    } 

    public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "requiredifattribute" 
     }; 
     modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty); 
     yield return modelClientValidationRule; 
    } 
} 

は、コードの最後のビットが他のすべてのコードを置き換えることに問題はありませんか?なぜバリデータクラスを保持するのですか?

+0

? –

+0

私はそれを見つけることができればいいが、私は傾ける。それは誰かの投稿に対するコメントのほうが多かった。あなたはそれについてどう思いますか? – CrazyDart

+0

私はまだ問題/質問が何であるかを理解しようとしているので、私は何も考えていません。私はちょうどいくつかのコンテキスト、特定のコード例などを見たいと思っていたので、あなたの質問で十分に提供していないので、より多くのコンテキストを表示しようとするためにソースを尋ねました。遭遇している問題の具体的なコード例をいくつか紹介してください。 –

答えて

10

CrazyDart、

IClientValidatableインターフェースはMVC3で添加しました。

2番目の例は、この新しいインターフェイスの有効な使用方法を示しています。あなたはそれを登録する必要はなく、検証に必要なクライアント側のルールを提供するだけでなく、必要なサーバー側の検証も行います。

先に、それを楽しんでください。

counsellorben

+1

それはあなたが正しいことが分かります。私はIClientValidatableを使用します。 ;-) – CrazyDart

+1

IClientValidatableについては、IClientValidatableの理解に基づいて、jqueryの検証アダプタと検証メソッドのためのクライアントサイドスクリプトを追加する必要があります。 – afr0

0

私はCrazyDartから最後のオプションを使用すると、サーバー側の部分がMVC4で素晴らしい作品。

例外として、クライアント側の検証が機能しない場合があります。クライアント側で必要なフィールドをチェックすることはありません(いくつかのタグが追加されていますが)。

私はこれについてサイモン・インスの第二のブログ記事を(第一は、ポスターのインスピレーションである)もチェックしました:あなたはこのアドバイスを読んでなかった http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

関連する問題