0

環境:
MVC4、Razor 2、および FluentValidation.MVC4 (3.4.6.0) を使用しています。

シナリオ:
次のように、子ビュー モデルもある特定のページの複雑なビュー モデルがあります。

public class ProfileViewModel
{
    public string FirstName {get; set;}
    public PhoneNumberViewModel Primary {get; set;}
    // ... other stuff ... //
}

public class PhoneNumberViewModel
{
    public string AreaCode { get; set; }
    public string Exchange { get; set; }
    public string Suffix { get; set; }
    public string Extension { get; set; }
}

このプロファイルは、更新のために編集および POST で戻すことができます。次のように、両方の Fluent Validators を作成しました。

public class ProfileViewModelValidator : AbstractValidator<ProfileViewModel>
{
    public ProfileViewModelValidator()
    {
        RuleFor(m => m.FirstName).NotEmpty().WithMessage("Please enter a First Name,");
        RuleFor(m => m.Primary).SetValidator(new PhoneNumberViewModelValidator()).WithMessage("Hello StackOverflow!");
        // ... other validation ... //
    }
}

public class PhoneNumberViewModelValidator : AbstractValidator<PhoneNumberViewModel>
{
    public PhoneNumberViewModelValidator()
    {
        RuleFor(m => m.AreaCode).NotEmpty();
    }     
}

そしてもちろん、すべてを表示するビューがあります。

プロフィール ビューのスニペット:

...
@Html.TextBoxFor(m => m.FirstName)
@Html.EditorFor(m => m.PrimaryPhoneNumber)
...

電話番号エディター テンプレート スニペット:

...
@Html.ValidationLabelFor(m => m, "Primary Phone:")
@Html.TextBoxFor(m => m.AreaCode)
@Html.TextBoxFor(m => m.Exchange)
@Html.TextBoxFor(m => m.Suffix)
@Html.TextBoxFor(m => m.Extension) 
@Html.ValidationMessageFor(m => m)
...

関連する場合は、バリデーターとさまざまなオブジェクトを自動的に結び付けるように設定しています。私は実際には.SetValidator()上記の行さえ必要としません...とにかく、配線のためにすべてが検証されます。

目的:
名を入力しないと、ValidationMessageFor によって作成された領域に上記のエラー メッセージが表示されます。ただし、子 PhoneNumberViewModel のいずれかの要素が検証に失敗した場合、何も得られません。.WithMessage()テキスト ボックスが赤色で強調表示されているのは素晴らしいことですが、 で指定した、子プロパティが無効であることを示すメッセージが表示されません。

現在、コントローラーで追加の作業を行うことでそれを達成しています...これは、子オブジェクトのエラーを探し、親オブジェクトにエラーを追加します。このアプローチは本当に、本当にひどいにおいがします。検証関連の問題をコントローラーに入れていますが、私はそれらをそこに入れたくありません。言うまでもなく、ModelState を掘り下げるために、文字列によるインデックス作成が大量に行われることにもなります。

子が検証に失敗した場合に ProfileViewModel のエラーを追加する ProfileViewModelValidator の検証ルールを定義する簡単な方法はありますか? および/またはそれは機能しているはずですが、何か間違っていますか? 私は検索して検索しましたが、満足のいく解決策が見つかりません。

御時間ありがとうございます!

4

1 に答える 1

0

質問に含めた臭いの解決策とは異なる解決策を発見しました。また、理想的とは言えませんが、上記の解決策よりも好ましいと思います。おそらく他の人も同意するでしょうから、より明確な答えが出るまでは役立つかもしれません。

PhoneNumberViewModel電話番号全体をフォーマットされた文字列として返すプロパティをに追加しました。

public string FullNumber
{
   get { return string.Format("{0}{1}{2}{3}", AreaCode, Exchange, Suffix, Extension); }
}

次に、各コンポーネントプロパティのルールに加えて、このプロパティに検証ルールを適用できます。.WithMessage()FullNumberプロパティにのみを適用すると、期待する検証メッセージ(および1回のみ)と、障害が発生した場合の個々のボックスのテキストボックスの強調表示の両方が表示されます。

このアプローチの主な欠点は、検証ルールを複製してしまうことです。各コンポーネントを個別に検証してから、結合されたプロパティも検証する必要があります。これは、基本的に、すでに実行した検証の組み合わせになります。コードが2倍になり、処理量が2倍になります。また、何かがうまくいかない可能性のある場所の数も2倍になります。

私の場合、正規表現を使用しているので、それほど悪くはありません...そして、コントローラーにエラー伝播コードを埋め込むよりも、正規表現を使用する方がはるかに好きです。しかし、それはまだ理想的ではありません-うまくいけば、より良い解決策がやってくるでしょう。

于 2013-01-24T23:45:52.540 に答える