0

Steven Sanderson による@Html.BeginCollectionItemヘルパーを使用しているときに、 IValidatableObjectインターフェイスを使用してサーバー側でコレクション項目を検証しようとしています。

ユーザーが 2 つの等しいアイテムを選択できないようにしたい。したがって、たとえば、ユーザーが話すイディオムのリストが与えられた場合、これらの値をポストバックできます。

English
English
Spanish

実装は次のValidateようになります。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    foreach(var idiom in Idioms)
    {
        if(Idioms.Any(i => i != idiom && i.Idiom == idiom.Idiom))
        {
            yield return new ValidationResult("Idiom already selected", new string[] { "Idiom" });
        }
    }
}

これの問題は、スティーブンのヘルパーが を使用し、次のように見えるためMemberName、 に渡された ("Idiom") が辞書にあるValidationResultものとは異なることです。MemberNameModelStateGuid

[42] = {[Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiom, System.Web.Mvc.ModelState]}

ご覧のとおりIdiom != [Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiom

最良の場合、たとえば[Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiomとして渡す方法MemberNameが必要ですが、 からこの情報を取得する方法がわかりませんvalidationContext。とにかくこれは動的でなければなりません。

これを克服する方法を知っていますか?

4

1 に答える 1

0

多くのグーグルの後、私は自分がやりたいことをする正しい方法を見つけました:

ASP.NET MVC 3 でのモデルの検証

コレクション/リストのプロパティを検証 (つまり、重複するエントリを見つける) するにはViewModel

@Html.ValidationMessageFor(u => u.Idioms)

あなたのプロパティのために、メソッドの中Viewで構成します。最後に、メッセージを正しいプロパティ名に割り当てます。つまり、私の場合です。errorMessageValidateIdioms

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    var grouping = Idioms.GroupBy(ui => ui.Idiom);

    var duplicates = grouping.Where(group => group.Count() > 1);

    if(duplicates.Any())
    {
        string message = string.Empty;

        foreach(var duplicate in duplicates)
        {
             message += string.Format("{0} was selected {1} times", duplicate.Key, duplicate.Count());
        }

        yield return new ValidationResult(message, new[] { "Idioms" });
    }
}

ボーナス

重複する各グループをseparate lines(改行を追加して<br>) 表示する場合は、次のようにします。

{0} was selected {1} timesと置き換えます{0} was selected {1} times<br>

次に、View側面でこれを行います:

@Html.Raw(HttpUtility.HtmlDecode(Html.ValidationMessageFor(u => u.Idioms).ToHtmlString()))

出力は次のようになります。

French was selected 2 times
English was selected 3 times
于 2013-10-01T20:27:21.307 に答える