2012-01-24 2 views
2

エディタテンプレートとコンポジションを使用してページを構築しています。私のビューモデルは、それ自身のビューモデルであるプロパティを含んでいます。例えば。親ビューモデルで特定の条件を指定すると、ビューモデル自体のプロパティのデータ注釈検証をオフにします。

public class ParentModel 
{ 
    public boolean SomeCheckBox { get; set; } 

    public ChildModel Child { get; set; } 
} 

public class ChildModel 
{ 
    [Required] 
    public string SomeString { get; set; } 

    [Required] 
    public string SomeOtherString { get; set; } 
} 

親のSomeCheckBoxプロパティがtrueの場合にのみ、データアノテーションの検証が子プロセスで実行されるようにしたいと思います。

私は、RequiredIfカスタム検証属性がstackoverflowのどこか別の場所にありますが、条件が同じビューモデルの値である場合にのみ機能します。私は、親、または確かに祖先の財産を確認できるものが必要です。

私の一時的なハックは、チェックボックスが真でない場合、ポストバック時のModelStateエラーをクリアすることです。

また、カスタムJavaScriptを作成して、チェックボックスがチェックされていないと、クライアントブラウザが検証を抑制するようにしなければなりませんでした。

実際の例はこれよりもはるかに複雑ですが、うまくいけば上の単純化された例からわかります。いいだろう何

public class ParentModel 
{ 
    public boolean SomeCheckBox { get; set; } 

    [SuppressValidationIf("SomeCheckBox", false)] 
    public ChildModel Child { get; set; } 
} 

任意のアイデアのようなもので、親ビューモデルの属性のですか?

答えて

6

この優れた例は、データの注釈である宣言的検証の限界を完全に示しています。

これは、多くのシナリオを処理できるように、検証ルールに不可欠なアプローチを使用することをお勧めします。 FluentValidation.NETは、この検証シナリオをケーキにしたライブラリの素晴らしい例です。

私はそれがこのシナリオを扱うことができる方法を説明してみましょう:

私達は私達の子供と親のモデルのためのバリデータを定義することによって開始:子バリデータはの値に基づいて含まれているか

public class ChildModelValidator : AbstractValidator<ChildModel> 
{ 
    public ChildModelValidator() 
    { 
     RuleFor(x => x.SomeString).NotEmpty(); 
     RuleFor(x => x.SomeOtherString).NotEmpty(); 
    } 
} 

public class ParentModelValidator : AbstractValidator<ParentModel> 
{ 
    public ParentModelValidator() 
    { 
     RuleFor(x => x.Child) 
      .SetValidator(new ChildModelValidator()) 
      .When(x => x.SomeCheckBox); 
    } 
} 

お知らせ親のプロパティSomeCheckBox?あなたのモデルは次のようになります:

[Validator(typeof(ParentModelValidator))] 
public class ParentModel 
{ 
    public bool SomeCheckBox { get; set; } 
    public ChildModel Child { get; set; } 
} 

public class ChildModel 
{ 
    public string SomeString { get; set; } 
    public string SomeOtherString { get; set; } 
} 

それだけです。

あなたは、単に、FluentValidation.MVC3 NuGetをインストールApplication_Startで次の行を追加します。

FluentValidationModelValidatorProvider.Configure(); 

を、今、あなたはいつものように動作します:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new ParentModel 
     { 
      Child = new ChildModel() 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(ParentModel model) 
    { 
     return View(model); 
    } 
} 

とビュー:

@model ParentModel 

@Html.ValidationSummary(false) 
@using (Html.BeginForm()) 
{ 
    @Html.CheckBoxFor(x => x.SomeCheckBox) 
    @Html.EditorFor(x => x.Child.SomeString) 
    @Html.EditorFor(x => x.Child.SomeOtherString) 
    <button type="submit">OK</button> 
} 

チェックボックスをオンにすると、子バリデーターが起動し、2 pロパティー。

+0

これは面白そうですね、ダーリンに感謝します。私はFluentValidationを見ていきます。ネット – magritte

+0

ちょっとダーリン、私は今これを試しています - それは実際にはサーバー側でうまくいきますが、.When()条件を含むバリデーターのためにクライアントサイドのJavaScriptを生成しないという点では少しばかりです。彼らはここでもhttp://fluentvalidation.codeplex.com/wikipage?title=mvcに言及しています。 .When()条件をサポートするためにクライアントサイドスクリプトの拡張を書いた人がいれば知っていますか?または、あなたのページにカスタム検証スクリプトを書いていますか? Cheers、Tony – magritte

+0

@TonyLeeper、このようなカスタム検証ロジックのために、私はカスタムのクライアント検証スクリプトを作成します。 –

関連する問題