我无法显示和保存导航属性。
我有 3 张桌子:
速率配置文件
- RateProfileID
- 个人资料名称
速度
- 费率ID
- RateProfileID
- 面板ID
- 数量
控制板
- 面板ID
- 面板名称
我有这些模型和外键的导航属性(即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
,即它会以每个面板的正确速率显示。但是,我的费率都不会与我的模型一起传递回控制器中的 HTTPPost 编辑方法。传递给我的RateProfile
控制器的 Rates 导航属性中将有 0 条记录(视图中有 28 条)。
有人建议我将 foreach 循环更改为 for(int i...) 循环。显然 foreach 循环将所有文本框命名为相同的东西,而常规 for 循环根据索引命名它们。
使用 for(int i...) 循环,当传递给 HTTPPost Edit 方法时,Rates 导航属性确实具有所有记录,并且我能够根据输入的内容更新这些记录。
但是...现在使用 for(int i...) 循环,页面将不会显示正确的记录(即使更改panelID
,它也始终显示默认记录)。panelID
更疯狂的是,如果我在视图中设置断点,我会看到正确的Rate
记录仍在传递给视图。我看到正确的RateID
/ amount
etc 都被放入 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
而不是我传递给视图的费率。
这是编辑方法的代码。我很确定问题出在视图中,因为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 循环
Rates
:根据 正确显示所有内容panelID
,但不会将值传递给控制器。for(int i...) 循环:将仅显示值
panelID == 1
并且不会基于panelID
. 将保存,但只保存与 关联的记录panelID == 1
。