MVC格式无法发布对象的列表 [英] MVC Form not able to post List of objects

查看:105
本文介绍了MVC格式无法发布对象的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个有问题的MVC Asp.net应用程序。从本质上讲,我有一个包含一个形式,其内容绑定到对象的列表视图。在这个循环中,它加载PartialView与物品被循环结束了。现在一切正常,截至形式的submittion。当它被提交的,所述控制器被发送对象的空列表。下面的code发现证明问题。

so I have an MVC Asp.net app that is having issues. Essentially, I have a View that contains a form, and its contents are bound to a list of objects. Within this loop, it loads PartialView's with the items being looped over. Now everything works up till the submittion of the form. When it gets submitted, the controller is sent a null list of objects. The code below demonstates the problems.

父视图:

@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:

_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>

而这些都是类以上code:

And these are the classes for the above code:

PlanViewModel:

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的枚举列表,但它是空。当检查发送的数据后,它发送正确的PARAMS。如果我要改变'的IEnumerable'到'的FormCollection,它包含了正确的价值观。任何人都可以看到为什么粘结剂没有建立正确的对象?我可以解决这个得到使用JavaScript,但失败的目的!任何帮助将大大AP preciated!

And the problem is in the controller action. As far as I am aware, it should be posting an enumerable list of PlanCompareViewModels, yet it is null. When in inspect the post data being sent, it is sending the correct params. And if I were to change 'IEnumerable' to 'FormCollection', it contains the correct values. Can anyone see why the binder is not creating the correct object? I can get around this using javascript, but that defeats the purpose! Any help would be greatly appreciated!

推荐答案

您模型,因为你提供的输入表单的方式表示该型号粘合剂没有办法在元件之间进行区分。眼下,这code:

Your model is null because the way you're supplying the inputs to your form means the model binder has no way to distinguish between the elements. Right now, this code:

@foreach (var planVM in Model)
{
    @Html.Partial("_partialView", planVM)
}

不提供任何形式的指数对这些项目的。所以它会反复生成HTML的输出是这样的:

is not supplying any kind of index to those items. So it would repeatedly generate HTML output like this:

<input type="hidden" name="yourmodelprefix.PlanID" />
<input type="hidden" name="yourmodelprefix.CurrentPlan" />
<input type="checkbox" name="yourmodelprefix.ShouldCompare" />

然而,正如你希望绑定到一个集合,你需要你的表单元素与索引命名,如:

However, as you're wanting to bind to a collection, you need your form elements to be named with an index, such as:

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

这指数是什么使得模型绑定到数据的独立的部分联系起来,允许其构造正确的模式。因此,这里是什么我建议你做些什么来解决它。而不是遍历您的收藏,使用的局部视图,利用模板的力量来代替。下面是你需要遵循的步骤:

That index is what enables the model binder to associate the separate pieces of data, allowing it to construct the correct model. So here's what I'd suggest you do to fix it. Rather than looping over your collection, using a partial view, leverage the power of templates instead. Here's the steps you'd need to follow:


  1. 创建视图的当前文件夹内的 EditorTemplates 文件夹(例如,如果你的观点是首页\\ Index.cshtml ,创建该文件夹首页\\ EditorTemplates )。

  2. 创建与该模型相匹配的名称目录中的强类型的视图。你的情况,这将是 PlanCompareViewModel.cshtml

  1. Create an EditorTemplates folder inside your view's current folder (e.g. if your view is Home\Index.cshtml, create the folder Home\EditorTemplates).
  2. Create a strongly-typed view in that directory with the name that matches your model. In your case that would be PlanCompareViewModel.cshtml.

现在,你在你的部分观点所拥有的一切希望在模板中去:

Now, everything you have in your partial view wants to go in that template:

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

最后,你父视图简化为这样的:

Finally, your parent view is simplified to this:

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

DisplayTemplates EditorTemplates 有足够的智慧,当他们正在处理的集合就知道了。这意味着他们将自动生成正确的名称,包括指数,为您的表单元素,这样就可以正确地绑定模型的集合。

DisplayTemplates and EditorTemplates are smart enough to know when they are handling collections. That means they will automatically generate the correct names, including indices, for your form elements so that you can correctly model bind to a collection.

这篇关于MVC格式无法发布对象的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆