2012-01-24 24 views
3

私はNinject.Web.Mvc.FluentValidationライブラリでFluent Validationを使用して、すべてのバリデーターを自動的にワイヤリングします(バリデーターを作成するために依存性注入を使用します)。子プロパティの選択的検証 - MVCでの流暢なバリデーション

私は、次のモデル作成:

public class ParentValidator : AbstractValidator<Parent> 
{ 
    public ParentValidator() 
    { 
     RuleFor(model => model.Name).NotEmpty(); 
     RuleFor(model => model.Child1).SetValidator(new ChildValidator()); 
    } 
} 

public class ChildValidator : AbstractValidator<Child> 
{ 
    public ChildValidator() 
    { 
     RuleFor(model => model.ChildProperty).NotEmpty(); 
    } 
} 

マイビュー:次のバリデータで

public class Parent 
{ 
    public string Name { get; set; } 

    public Child Child1 { get; set; } 
    public Child Child2 { get; set; } 
} 

public class Child 
{ 
    public string ChildProperty { get; set; } 
} 

を私が達成しようとしています何

@model Parent 

@using(Html.BeginForm()) 
{ 
    @Html.EditorFor(model => model.Name) 
    @Html.ValidationMessageFor(model => model.Name) 

    @Html.EditorFor(model => model.Child1) 
    @Html.EditorFor(model => model.Child2) 

    <input type="submit" value="Save" /> 
} 

@model Child 

@Html.EditorFor(model => model.ChildProperty) 
@Html.EditorFor(model => model.ChildProperty) 

は、親を持つことです2つの子プロパティを持つモデル。 Child1のプロパティは必須ですが、Child2のプロパティはオプションです。正常な状況では正常に動作しますが、Ninjectモジュールを使用してバリデーターを自動的にワイヤリングすると、Childクラスのバリデータ型が検出され、ParentのすべてのChildプロパティが配線されます。

Ninjectモジュールを削除しなければ、これが起こらないようにする方法はありますか?自動wireupは条件付きで結合モデルの間ChildValidatorクラスを適用する際に理解するための方法を持っていないので、あなたは、いくつかの選択肢を持っているように、それはそう

答えて

2

  1. を決めた子の再利用の場合それが重要です。このような状況に直面して、Childオブジェクトがあまり複雑でなく、Childオブジェクトを別々に使用したビューが2つ以上ない場合、おそらくこのビューの親に子を折りたたんでいます。ページ構造は私の経験では時間の経過とともにばらつく傾向があるので、私はいつもビューモデルでスーパーDRYになるのがやや嫌です。
  2. Clear ModelState errors for Child2.ここから、この固有のコンテキストでChild2の個別のバリデーターを含め、Child2の検証を完全に制御し、手動で適用することができます。 FluentValidationが好きな理由の1つは、データアノテーションとは異なり、異なるコンテキストで同じビューモデルに異なる検証ロジックを適用できることです。

auto-wireupの値(つまり、それが排除するすべての余分なコード)は、この1つのケースIMOに対してこれをオフにするオプションを排除します。

0

あなたは2番目の子プロパティにバリデータを設定するのを忘れ:

public class ParentValidator : AbstractValidator<Parent> 
{ 
    public ParentValidator() 
    { 
     RuleFor(model => model.Name).NotEmpty(); 
     RuleFor(model => model.Child1).SetValidator(new ChildValidator()); 
     RuleFor(model => model.Child2).SetValidator(new ChildValidator()); 
    } 
} 
+1

アセンブリですべてのバリデーターを自動的にワイヤリングするNinjectモジュールを使用しているので、これを行う必要はありませんでした。 – Dismissile

0

あなたは子供のバリデータに空のインタフェースを追加することができますバリwireup子autoにしたくない場合は、次の

パブリッククラスPersonalDataValidator:AbstractValidator 、

そして、あなたの工場でIChildValidator

public class FluentValidatorFactory : ValidatorFactoryBase 
{ 
    private readonly IKernel _kernel; 

    public FluentValidatorFactory(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    public override IValidator CreateInstance(Type validatorType) 
    { 
     IValidator validator = _kernel.Resolve(validatorType) as IValidator; 

     ////we dont want that windosr auto wires up all child validators. 
     var childValidator = validator as IChildValidator; 

     if (childValidator == null) 
     { 
      return validator; 
     } 

      return null; 
    } 
} 
関連する問題