我有3张桌子:
RateProfile
率
面板
我有每个模型。我有一个使用RateProfile模型的编辑页面。我显示RateProfile的信息以及与之关联的所有费率。这工作正常,我可以更新它。但是,我还添加了一个下拉列表,以便我可以按PanelID过滤费率。我需要它回发更改,以便它可以显示过滤后的费率。
我正在使用
@Html.DropDownList("PanelID", (SelectList)ViewData["PanelDropDown"], new { onchange = "$('#RateForm').submit()" })
我的下拉列表。每当它回发到我的HttpPost Edit方法时,它似乎都缺少关于Rates导航属性的所有信息。这很奇怪,因为我认为它会完全按照我在表单中的输入/提交按钮执行(实际上将整个模型传递回我的HttpPost Edit操作并完成我想要它做的事情)。 panelID正确传递给我的HttpPost Edit方法并传递到下一个视图,但是当我尝试查询Model.Rates导航属性为null时(仅当帖子来自下拉列表时。当帖子来自时,一切正常)我的提交输入)。
获取编辑:
public ActionResult Edit(int id, int panelID = 1)
{
RateProfile rateprofile = db.RateProfiles.Single(r => r.RateProfileID == id);
var panels = db.Panels;
ViewData["PanelDropDown"] = new SelectList(panels, "PanelID", "PanelName", panelID);
ViewBag.PanelID = panelID;
return View(rateprofile);
}
HttpPost编辑:
[HttpPost]
public ActionResult Edit(RateProfile rateprofile, int panelID)
{
var panels = db.Panels;
ViewData["PanelDropDown"] = new SelectList(panels, "PanelID", "PanelName", panelID);
ViewBag.PanelID = panelID;
if (ModelState.IsValid)
{
db.Entry(rateprofile).State = EntityState.Modified;
foreach (Rate dimerate in rateprofile.Rates)
{
db.Entry(dimerate).State = EntityState.Modified;
}
db.SaveChanges();
return View(rateprofile);
}
return View(rateprofile);
}
查看:
@model PDR.Models.RateProfile
@using (Html.BeginForm(null,null,FormMethod.Post, new {id="RateForm"}))
{
<div>
@Html.Label("Panel")
@Html.DropDownList("PanelID", (SelectList)ViewData["PanelDropDown"], new { onchange = "$('#RateForm').submit()" })
</div>
@{var rates= Model.Rates.Where(a => a.PanelID == ViewBag.PanelID).OrderBy(a => a.minCount).ToList();}
@for (int i = 0; i < rates.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(modelItem => rates[i].RateProfileID)
@Html.HiddenFor(modelItem => rates[i].RateID)
@Html.HiddenFor(modelItem => rates[i].PanelID)
@Html.EditorFor(modelItem => rates[i].minCount)
@Html.ValidationMessageFor(model => rates[i].minCount)
</td>
<td>
@Html.EditorFor(modelItem => rates[i].maxCount)
@Html.ValidationMessageFor(model => rates[i].maxCount)
</td>
<td>
@Html.EditorFor(modelItem => rates[i].Amount)
@Html.ValidationMessageFor(model => rates[i].Amount)
</td>
</tr>
}
<input type="submit" value="Save" />
}
总结一下我的问题,我的视图中的以下查询仅在帖子来自提交按钮时有效,而不是来自我的下拉列表。
@{var rates= Model.Rates.Where(a => a.PanelID == ViewBag.PanelID).OrderBy(a => a.minCount).ToList();}
答案 0 :(得分:0)
它在渲染页面中的外观如何?您可能有两个使用相同名称/ ID呈现的元素:
@Html.DropDownList("PanelID", (SelectList)ViewData["PanelDropDown"], new { onchange = "$('#RateForm').submit()"
和
@Html.HiddenFor(modelItem => rates[i].PanelID)
答案 1 :(得分:0)
我建议您使用Firefox / Firebug来检查它的实际请求。我无法想象如果通过提交与按钮触发,表单将以不同方式发布,但我认为这是可能的。
更重要的是,我会对你的设计做一些评论。
我会使用ViewBag属性进行选择,而不是基于对ViewData的基于密钥的访问。这在您的控制器和视图中都更具可读性。
考虑使用单独的操作填充由下拉列表过滤的信息。在您的视图中基于PanelID渲染该操作,并通过AJAX调用该操作以获取新的HTML而不是完整的表单。
避免在标记中应用处理程序。而是将可选的“脚本”部分添加到母版页,并在需要时向页面添加脚本,以通过该部分应用您的行为。这允许您通过主控件来控制特定于视图的脚本放置在文档中,并将您的行为与文档结构分开,这是可读性的最佳实践。
答案 2 :(得分:0)
我发现了问题。看起来因为我只是循环浏览导航属性的一个子集(由panelID过滤的速率),从视图返回的模型只有可用的导航属性子集。保存更改后,我刚刚重新定义了我的模型(再次从数据库中调用了记录),现在看起来很好。
IE中。在我的导航属性中应该有140条记录,按panelID == 1将其缩小到28条记录。由于某种原因,实体框架决定它不想维持与其他112条记录的关系,所以当我将下拉列表更改为按panelID == 2过滤时,唯一可用的记录都有panelID == 1并返回null