4

Ninject.Web.Mvc.FluentValidationライブラリでFluentValidationを使用して、すべてのバリデーターを自動的に接続しています(依存性注入を使用してバリデーターを作成しています)。

次のモデルを作成しました。

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; }
}

次のバリデーターを使用します。

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();
    }
}

私の見解:

@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モジュールを削除せずにこれが発生するのを防ぐ方法はありますか?

4

3 に答える 3

2

自動配線には、モデルのバインド中にChildValidatorクラスをいつ適用するかを条件付きで理解する方法がないため、いくつかの選択肢があるようです。

  1. 子ビューモデルの再利用がそれほど重要かどうかを判断します。 この状況に直面して、子オブジェクトがそれほど複雑でなく、子オブジェクトを個別に使用するビューが2つ以下の場合は、おそらく子をこのビューの親に折りたたむでしょう。私の経験では、ページ構造は時間の経過とともに発散する傾向があるため、ビューモデルを使用してスーパードライにすることには常に少し消極的です。
  2. Child2のModelStateエラーをクリアします。 ここから、Child2の検証を完全に制御できます。これには、この独自のコンテキストでChild2の個別のバリデーターを含め、手動で適用することも含まれます。これが、FluentValidationが大好きな理由の1つです。データ注釈とは異なり、異なるコンテキストの同じビューモデルに異なる検証ロジックを適用する機能です。

自動配線の価値(つまり、それが排除するすべての余分なコード)は、この1つのケースであるIMOに対してそれをオフにするオプションを除外します。

于 2012-02-20T02:49:10.230 に答える
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());
    }
}
于 2012-02-23T10:53:06.163 に答える
0

子バリデーターを自動配線したくない場合は、子バリデーターに空のインターフェースを追加できます。

パブリッククラス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;
    }
}
于 2014-07-04T11:30:22.677 に答える