所以我有一个MVC Asp.net应用程序有问题。本质上,我有一个包含表单的View,其内容绑定到对象列表。在此循环中,它将加载PartialView以及正在循环的项目。现在一切正常,直到提交表单为止。提交后,将向控制器发送空对象列表。下面的代码演示了这些问题。
父视图:
@model IEnumerable<PlanCompareViewModel> @using (Html.BeginForm("ComparePlans", "Plans", FormMethod.Post, new { id = "compareForm" })) { <div> @foreach (var planVM in Model) { @Html.Partial("_partialView", planVM) } </div> }
_partialView:
@model PlanCompareViewModel <div> @Html.HiddenFor(p => p.PlanID) @Html.HiddenFor(p => p.CurrentPlan) @Html.CheckBoxFor(p => p.ShouldCompare) <input type="submit" value="Compare"/> </div>
这些是上述代码的类:
PlanViewModel:
public class PlansCompareViewModel { public int PlanID { get; set; } public Plan CurrentPlan { get; set; } public bool ShouldCompare { get; set; } public PlansCompareViewModel(Plan plan) { ShouldCompare = false; PlanID = plan.PlanId; CurrentPlan = plan; } public PlansCompareViewModel() { // TODO: Complete member initialization } public static IEnumerable<PlansCompareViewModel> CreatePlansVM(IEnumerable<Plan> plans) { return plans.Select(p => new PlansCompareViewModel(p)).AsEnumerable(); } }
控制器:
public class PlansController : MyBaseController { [HttpPost] public ActionResult ComparePlans(IEnumerable<PlanCompareViewModel> model) { //the model passed into here is NULL } }
问题出在控制器动作上。据我所知,它应该发布一个可枚举的PlanCompareViewModels列表,但它为null。在检查正在发送的帖子数据时,它正在发送正确的参数。如果我将“ IEnumerable”更改为“ FormCollection”,则它包含正确的值。谁能看到活页夹为什么没有创建正确的对象?我可以使用javascript解决这个问题,但这违背了目的!任何帮助将不胜感激!
null之所以建立模型,是因为您向表单提供输入的方式意味着模型联编程序无法区分元素。现在,此代码:
null
@foreach (var planVM in Model) { @Html.Partial("_partialView", planVM) }
没有为这些项目提供任何类型的索引。因此它将反复生成如下HTML输出:
<input type="hidden" name="yourmodelprefix.PlanID" /> <input type="hidden" name="yourmodelprefix.CurrentPlan" /> <input type="checkbox" name="yourmodelprefix.ShouldCompare" />
但是,由于要绑定到集合,因此需要使用索引来命名表单元素,例如:
<input type="hidden" name="yourmodelprefix[0].PlanID" /> <input type="hidden" name="yourmodelprefix[0].CurrentPlan" /> <input type="checkbox" name="yourmodelprefix[0].ShouldCompare" /> <input type="hidden" name="yourmodelprefix[1].PlanID" /> <input type="hidden" name="yourmodelprefix[1].CurrentPlan" /> <input type="checkbox" name="yourmodelprefix[1].ShouldCompare" />
该索引使模型绑定器能够关联单独的数据,从而构建正确的模型。所以这是我建议您修复的方法。而不是使用局部视图来遍历您的集合,而是利用模板的功能。这是您需要遵循的步骤:
EditorTemplates
Home\Index.cshtml
Home\EditorTemplates
PlanCompareViewModel.cshtml
现在,您在部分视图中拥有的所有内容都希望进入该模板:
最后,您的父视图简化为:
@model IEnumerable<PlanCompareViewModel> @using (Html.BeginForm("ComparePlans", "Plans", FormMethod.Post, new { id = "compareForm" })) { <div> @Html.EditorForModel() </div> }
DisplayTemplates并且EditorTemplates足够聪明,知道他们何时处理集合。这意味着它们将自动为表单元素生成正确的名称(包括索引),以便您可以对绑定到集合的模型进行正确建模。
DisplayTemplates