ナビゲーションプロパティの表示と保存に問題があります。
私は3つのテーブルを持っています:
RateProfile
- RateProfileID
- プロファイル名
レート
- RateID
- RateProfileID
- PanelID
- 額
パネル
- PanelID
- PanelName
これらのそれぞれのモデルと外部キーのナビゲーションプロパティがあります(つまりRates
、のナビゲーションプロパティですRateProfile
)。RateProfile
モデルとして編集ページがあります。このページには、のドロップダウンがありPanelID
ます。ドロップダウンは、表示されるナビゲーションプロパティをフィルタリングします(それぞれpanelID
に28のレートが関連付けられています)。ドロップダウンが変更されるたびに、私のメソッドに投稿されEdit
ます(次に進む前に既存のデータを保存し、新しく選択されたレートを表示するためpanelID
)。
必要な料金レコードのみを、を介してリストのビューに渡しますViewBag
。
私は最初にforeachループを使用していました
foreach(PDR.Models.Rate rate in ViewBag.Rates){
@Html.HiddenFor(modelItem => rate.RateProfileID)
@Html.HiddenFor(modelItem => rate.RateID)
@Html.HiddenFor(modelItem => rate.PanelID)
@Html.EditorFor(modelItem => rate.Amount)
@Html.ValidationMessageFor(modelItem => rate.Amount)
}
foreachループを使用すると、のドロップダウンを変更したときにすべてが正しく表示されますPanelID
。つまり、各パネルの正しいレートで表示されます。ただし、どのレートもモデルと一緒にコントローラーのHTTPPostEditメソッドに戻されませんでした。コントローラにRateProfile
渡されると、Ratesナビゲーションプロパティに0レコードが含まれます(ビューには28レコードがあります)。
foreachループをfor(int i ...)ループに変更するようにアドバイスされました。どうやらforeachループはすべてのテキストボックスに同じ名前を付け、通常のforループはインデックスに基づいてそれらに名前を付けます。
for(int i ...)ループを使用すると、Ratesナビゲーションプロパティには、HTTPPost Editメソッドに渡されたときに実際にすべてのレコードがあり、入力した内容に基づいてこれらのレコードを更新できました。
ただし...for(int i ...)ループを使用すると、ページにはに基づいた正しいレコードが表示されませんpanelID
(変更された場合でも常にデフォルトのレコードが表示されますpanelID
)。さらにクレイジーなのは、ビューにブレークポイントを設定すると、正しいRate
レコードがまだビューに渡されていることを確認できることです。正しいRateID
/amount
などがすべてHtmlヘルパーに入力されていることがわかりますが、ページが実際に表示されると、デバッグモードで入力されているのを見ていましたが、ドロップダウンを変更する前にあったデータが表示されます。
foreachループから通常のforループに切り替えてから使用しているビューコードは次のとおりです。
@{List<PDR.Models.Rate> rates = ViewBag.rates;
var count = rates.Count;
}
@for (int i = 0; i < count; i++)
{
@Html.HiddenFor(modelItem => rates[i].RateProfileID)
@Html.HiddenFor(modelItem => rates[i].RateID)
@Html.HiddenFor(modelItem => rates[i].PanelID)
@Html.EditorFor(modelItem => rates[i].Amount)
@Html.ValidationMessageFor(modelItem => rates[i].Amount)
}
私の見解では、デバッグモードで値をチェックすることから、にViewBag.rates
基づいて正しいレートが渡されていることがわかりpanelID
ます。RateID,PanelID
問題は、デバッグでステップスルーして、の正しい値が設定されるのを見ることができてもAmount
、上記のループの各レートについて、実際にページに表示されるのは常にの値でpanelID == 1
あり、次にに渡される値です。私のコントローラーはpanelID == 1
、ビューに渡したレートではなく、常にレートの値です。
これがeditメソッドのコードです。ただし、問題はビューにあると確信しています。これは、rateprofile
(ビューのモデルである必要があります)が最初から正しいナビゲーションプロパティを取得していないためです。
[HttpPost]
public ActionResult Edit(RateProfile rateprofile, int panelID)
{
var panels = db.Panels;
ViewBag.PanelDropDown = new SelectList(panels, "PanelID", "PanelName", panelID);
ViewBag.PanelID = panelID;
if (ModelState.IsValid)
{
db.Entry(rateprofile).State = EntityState.Modified;
foreach (Rate rate in rateprofile.Rates)
{
db.Entry(rate).State = EntityState.Modified;
}
db.SaveChanges();
}
rateprofile = db.RateProfiles.Include(a => a.Rates).Where(a => a.RateProfileID == rateprofile.RateProfileID).Single(); //reloads the current rateprofile from the db
PopulatePanelDropDown(rateprofile, panelID); //populates the ViewBag.rates variable
return View(rateprofile);
}
要約すれば:
foreach loop over
Rates
:に基づいてすべてを適切に表示しますpanelID
が、コントローラーに値を渡しません。for(int i ...)loop:の値のみを表示し
panelID == 1
、に基づいて更新しませんpanelID
。保存しますが、に関連付けられているレコードのみpanelID == 1
です。