gpt4 book ai didi

c# - MVC 表单无法发布对象列表

转载 作者:IT王子 更新时间:2023-10-29 03:53:31 27 4
gpt4 key购买 nike

所以我的 MVC Asp.net 应用程序有问题。本质上,我有一个包含表单的 View ,其内容绑定(bind)到一个对象列表。在此循环中,它加载带有循环项目的 PartialView。现在一切正常,直到提交表格。当它被提交时, Controller 会收到一个空对象列表。下面的代码演示了这些问题。

父 View :

@model IEnumerable<PlanCompareViewModel>
@using (Html.BeginForm("ComparePlans", "Plans", FormMethod.Post, new { id = "compareForm" }))
{
<div>
@foreach (var planVM in Model)
{
@Html.Partial("_partialView", planVM)
}
</div>
}

_部分 View :

@model PlanCompareViewModel
<div>
@Html.HiddenFor(p => p.PlanID)
@Html.HiddenFor(p => p.CurrentPlan)
@Html.CheckBoxFor(p => p.ShouldCompare)
<input type="submit" value="Compare"/>
</div>

这些是上面代码的类:

平面 View 模型:

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();
}
}

Controller :

public class PlansController : MyBaseController
{
[HttpPost]
public ActionResult ComparePlans(IEnumerable<PlanCompareViewModel> model)
{
//the model passed into here is NULL
}
}

问题出在 Controller 操作上。据我所知,它应该发布一个可枚举的 PlanCompareViewModels 列表,但它是空的。在检查正在发送的帖子数据时,它正在发送正确的参数。如果我将“IEnumerable”更改为“FormCollection”,它包含正确的值。谁能看出 Binder 为什么没有创建正确的对象?我可以使用 javascript 解决这个问题,但这违背了目的!任何帮助将不胜感激!

最佳答案

您的模型是 null 因为您向表单提供输入的方式意味着模型绑定(bind)器无法区分元素。现在,这段代码:

@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" />

但是,当您想要绑定(bind)到一个集合时,您需要使用索引来命名您的表单元素,例如:

<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" />

该索引使模型绑定(bind)器能够关联单独的数据片段,从而使其能够构建正确的模型。因此,这就是我建议您修复它的方法。与其循环遍历您的集合,不如使用局部 View ,而是利用模板的力量。以下是您需要遵循的步骤:

  1. 在 View 的当前文件夹中创建一个 EditorTemplates 文件夹(例如,如果您的 View 是 Home\Index.cshtml,则创建文件夹 Home\EditorTemplates).
  2. 在该目录中创建一个名称与您的模型匹配的强类型 View 。在您的情况下,这将是 PlanCompareViewModel.cshtml

现在,您在局部 View 中拥有的所有内容都希望进入该模板:

@model PlanCompareViewModel
<div>
@Html.HiddenFor(p => p.PlanID)
@Html.HiddenFor(p => p.CurrentPlan)
@Html.CheckBoxFor(p => p.ShouldCompare)
<input type="submit" value="Compare"/>
</div>

最后,您的父 View 被简化为:

@model IEnumerable<PlanCompareViewModel>
@using (Html.BeginForm("ComparePlans", "Plans", FormMethod.Post, new { id = "compareForm" }))
{
<div>
@Html.EditorForModel()
</div>
}

DisplayTemplatesEditorTemplates 足够聪明,知道它们何时处理集合。这意味着它们会自动为您的表单元素生成正确的名称,包括索引,以便您可以正确地建模绑定(bind)到集合。

关于c# - MVC 表单无法发布对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19964553/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com