1

ViewModel が (コレクションを持っている) 場合、ViewModel プロパティを対応する ModelState.Key 値に一致させることは可能ですか?

例: ビューモデル アイテムのコレクションを編集するために、ここにある拡張機能を使用しています

これにより、ページ上のフィールドの ID に GUID が追加されます。

例:

class Pets
{
    string animal;
    string name;
}

ペットのリストの場合、生成された html ソースは次のようになります。

<input name="Pets.index" autocomplete="off" value="3905b306-a9..." type="hidden">
<input value="CAT" id="Pets_3905b306-a9...__animal" name="Pets[3905b306-a9...].animal" type="hidden">
<input value="MR. PEPPERS" id="Pets_3905b306-a9...__name" name="Pets[3905b306-a9...].name" type="hidden">


<input name="Pets.index" autocomplete="off" value="23342306-b4..." type="hidden">
<input value="DOG" id="Pets_23342306-b4...__animal" name="Pets[23342306-b4...].animal" type="hidden">
<input value="BRUTICUS" id="Pets_23342306-b4...__name" name="Pets[23342306-b4...].name" type="hidden">

したがって、これがポストにバインドされると、ModelState にすべてのフォーム フィールドがロードされます。ModelSTate.Keys には、次のものがあります。

Pets[23342306-b4...].name
Pets[23342306-b4...].animal
Pets[3905b306-a9...].name
Pets[3905b306-a9...].animal

これまでのところすべて順調ですが、同じ名前の動物が存在する場合、新しい動物を追加できないなど、いくつかのビジネス ロジックの検証を行っています。その場合、エラーになっている入力フィールドを強調表示できるようにしたいと考えています。

したがって、作成関数が失敗した場合、次のようなエラー/キー値のペアが返されます。

{ error = "Duplicate Name", key="name" }

したがって、少なくともどのプロパティが問題を引き起こしたのかを説明します。

しかし、リポジトリ関数はビュー フィールド ID を認識していないため、キー「name」を適切な ModelState キー (この場合は Pets[23342306-b4...].name または Pets[3905b306) に一致させるにはどうすればよいですか? -a9...].name)?

4

2 に答える 2

0

MVC の組み込み機能を使用してコレクション (Html.DisplayFor(m => m.Pets)またはHtml.EditorFor(m => m.Pets)) を適切な表示/エディター テンプレートで表示する場合、MVC は次のようにレンダリングします。

Pets[0].name
Pets[0].animal
Pets[1].name
Pets[1].animal

これはにマップされIEnumerable<Pets>、最初のアイテムのインデックスが 0、2 番目のアイテムが 1 などであることがわかります。

したがって、2 番目の項目にエラーがある場合は、たとえばModelStateキーにエラーを設定できます。"Pets[1].name"

于 2012-10-13T09:31:07.397 に答える
0

私のように Html.BeginCollectionItem 拡張メソッドを使用している場合は、GUID を使用しないことでこれを回避できました。動的な追加と削除が必要ですが、エディターにある既知のアイテム、ID を持つ人物を常に検索していました。したがって、GUID を使用する代わりに、以下のコードで ID (uniqueId) を割り当てるだけです。それが Person[234232] であることはわかっていたので、キーを見つけることができました。もちろん、新しいアイテムを追加していて、選択したアイテムを表示していない場合は、うまくいかないかもしれません.

        public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName, string uniqueId)
    {
        var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
        string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : uniqueId;

        // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
        html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));

        return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
    }
于 2013-04-03T21:21:17.903 に答える