3

現在、一連のチェックボックスに基づいて一括更新を作成しようとしています。エンティティ フレームワークを使用してそれを行う正しい方法が見つからないようです。

MVC3 と Razor で ASP.Net 4 を使用しています。

ここに私がこれまでに持っているコードがあります。

ページを表示 (正常に動作)

@model List<LeagueCounters.Models.champion>
<form name="setFree id="setFree" method="POST" action="/Champion/SetFree">
    @foreach (var item in Model)
    {
        if (item.isFree == true)
        {
           <input type="checkbox" id="@item.id" checked="checked" /> @Html.DisplayFor(modelItem => item.displayName)  
        }
        else
        {
            <input type="checkbox" id="@item.id" /> @Html.DisplayFor(modelItem => item.displayName)
        }
    }
<p><input type="submit" value="Save" /></p>

コントローラー (エラー)

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult SetFree(FormCollection fcMain)
{
     var sortedList = from c in _db.champions
                      orderby c.name
                      select c;
     int counter = 0;
     foreach (champion champ in sortedList)
     {
         if (fcMain[counter].Contains("true"))
            champ.isFree = true;
         else
            champ.isFree = false;

         _db.champions.Attach(champ);
         _db.ObjectStateManager.ChangeObjectState(champ, EntityState.Modified);

         counter++;
     }

     _db.SaveChanges();

     return View();
}

エラー

インデックスが範囲外でした。負ではなく、コレクションのサイズより小さくなければなりません。パラメータ名:インデックス

質問

コントローラのチェックボックスを適切に切り替えるにはどうすればよいですか? そして、その時点に到達したら、大量更新コードは機能しますか?

前もって感謝します。

4

2 に答える 2

2

ここでの問題は、チェックされたチェックボックスのみがサーバーに送信されることです。したがって、すべてのチェックボックス キーがフォーム コレクションに存在するとは期待できません。この動作を回避するにHtml.CheckBoxForは、チェックボックス付きの追加の非表示フィールドを作成して、サーバー側で結果を読み取ることができるようにします。ループでデータをレンダリングしているため、ここで強く型付けされたヘルパーをどのように使用するかわかりません。こちらのグーグル検索でご覧いただけると思います

于 2012-07-17T10:46:27.717 に答える
0

このラインだと思います

fcMain[counter].Contains("true")

Whereエラーを引き起こしています..モデルをビューに提供するときに、ある種の制約選択()を使用していますか

?また、すべてのチェックボックスの後に隠しフィールドを追加する必要があります

<input type="hidden" value="false" id="@item.id" name="@item.id"/>

このようにして、すべてのチェックボックスが正常に送信され、値
分割して、サーバー側に存在する最初の値を取得する必要があります。
または、両方をスキップしてこの方法を直接使用すると@Html.Checkbox(item.Id,item.isFree)、コードがよりクリーンになり、手動で追加する必要がなくなります。Razor エンジンHidden Inputによって自動的に追加されます。 コードを保持するためにできるその他の改善点もあります。 これを変える

DRY

if (item.isFree == true)
{
   <input type="checkbox" id="@item.id"  checked="checked" /> @Html.DisplayFor(modelItem => item.displayName)  
}
else
{
   <input type="checkbox" id="@item.id" /> @Html.DisplayFor(modelItem => item.displayName)
}

<input type="checkbox" id="@item.id" name="@item.id" @(!Item.isFree?"checked=\"checked\":\"\"") /> @Html.DisplayFor(modelItem => item.displayName)

そして、私はあなたがこれらを必要とは思わない

_db.champions.Attach(champ);
_db.ObjectStateManager.ChangeObjectState(champ, EntityState.Modified);
于 2012-07-17T10:20:27.227 に答える