Dictionary (およびこの質問には関係のないもの) を含む ViewModel クラスがあります。
public class MyViewModel {
public Dictionary<int, string> Data { get; set; }
/* ... */
}
次に、辞書を扱うGET
/アクションがいくつかあります。POST
このGET
アクションは、最初Dictionary<int, string>
にデータベースからのデータを入力してから、次の値を返しますView
。
.Key
s は隠しフィールドになります。と.Value
s は、ユーザーが編集するためのテキストエリアになります。
ユーザーはこのフォームを送信し、アクションを呼び出しPOST
ます。入力を処理しようとします (プロセスは関係ありません)。Key
/Value
ペアの一部は有効で、一部は無効です。
無効なペアがある場合、アクションはViewModelPOST
を再構築しますが、今回はディクショナリに無効なペアのみを含める必要があり、ユーザーが修正して再送信できるように同じビューを再表示します。
質問:これを達成するための最も簡単でクリーンな方法は何ですか?
私がこれまでに持っているもの(正常に動作しています)、コントローラー:
public ActionResult MyAction(MyViewModel vm) {
/* Process data */
if (are there invalid pairs?) {
var vmErrors = new MyViewModel();
/* ... fill the ViewModel ... */
vmErrors.Data =
vm.Data
.Where(x => IsInvalid(x))
.ToDictionary(x => x.Key, x => x.Value);
return View(vmErrors);
}
}
そしてビュー:
<% var i = 0; foreach (var p in Model.Data) { %>
<%= Html.Hidden("vm.Data[" + i + "].key", vm.Key %>
<%= Html.TextArea("vm.Data[" + i + "].value", vm.Value %>
<% i++; } %>
問題は、モデル バインダーを喜ばせるために、ビューのフィールドに連続した ID を付けなければならないことです。ただし、ディクショナリを繰り返し処理してキーと値のペアを抽出する必要があるため、for (var i = 0; i < Model.Data.Count; i++) {...}
ループになることはありません。