在PartialView MVC多种形式的回传返回null除了一日一上市 [英] MVC Multiple forms in PartialView returns null on postback for except the 1st one listed

查看:146
本文介绍了在PartialView MVC多种形式的回传返回null除了一日一上市的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我希望有人在那里可以帮我在这一个(在此先感谢!)。我使用MVC4。

我ContractsModel包含(除其他事项外)ContractModel(S)的列表。在我的部分观点,我虽然循环列表创建为每一种形式。到现在为止还挺好。问题是上回发。首届形式总是回发的罚款。但其他(2,3,4,等)总是返回空

我和调试工具检查,证实所呈现的控制是适当命名的。

 <选择名称=合同[0] .OrganizationIdID =Contracts_0__OrganizationId>
<选择名称=合同[1] .OrganizationIdID =Contracts_1__OrganizationId>
<选择名称=合同[2] .OrganizationIdID =Contracts_2__OrganizationId>

我也证实了客户确实是将数据返回到服务器,但由于某种原因,它似乎并没有被越来越重视回到我的ActionResult期待模型。任何想法?

我已经尽量减少我的code为简洁。

下面是我的模型:

 公共类ContractsModel
{
    公共ContractsModel()
    {
        this.Contracts =新的List< ContractModel>();        this.OrganizationList =新的List< SelectListItem>();
        this.ContractNumList =新的List< SelectListItem>();
    }    公共字符串ParentProjectId {搞定;组; }
    //等等,等等.....    公开名单< ContractModel>合同{搞定;组; }    公开名单< SelectListItem> OrganizationList {搞定;组; }
    公开名单< SelectListItem> ContractNumList {搞定;组; }
}
公共类ContractModel
{
    公共字符串OrganizationId {搞定;组; }
    公共字符串组织{搞定;组; }
    公共字符串ContractNumId {搞定;组; }
    公共字符串ContractNum {搞定;组; }
}

下面是我的控制器动作

  [HttpPost]
公众的ActionResult _ContractsEdit(ContractsModel模型)
{    如果(ModelState.IsValid){
        //等等等等等等....
    }    返回PartialView(指数,ProjectModel);
}

下面是我的局部视图

  @model Manager.Models.ContractsModel@for(INT I = 0; I< Model.Contracts.Count();我++)
{
    变种DIVID =divContractsModelItem_+第(i + 1);
    变种saveButtonId =btnContractsEditSave_+第(i + 1);
    < D​​IV ID =@divId>        @using(Html.BeginForm(_ ContractsEdit,项目,FormMethod.Post))
        {
            <&字段集GT;
                <传奇>常规:LT; /传说>                < D​​IV>
                    <标签>缔约组织:LT; /标签>
                    @ Html.DropDownListFor(型号=> model.Contracts [I] .OrganizationId,新的SelectList(Model.OrganizationList,价值,文本,Model.Contracts [I] .OrganizationId))
                < / DIV>                < D​​IV>
                    <标签>合同编号:LT; /标签>
                    @ Html.DropDownListFor(型号=> model.Contracts [I] .ContractNumId,新的SelectList(Model.ContractNumList,价值,文本,Model.Contracts [I] .ContractNumId))
                < / DIV>                < D​​IV>
                   <按钮ID =@ saveButtonId类型=提交>保存< /按钮>
                < / DIV>            < /字段集>
        }
    < / DIV>}


解决方案

由于我的意见帮你,我想我会割肉出来作为一个完整的答案。

与模型结合的问题是,它不允许跳过数组索引 - 一旦一个被跳过,它停止结合。你的页面有多种形式,每个合同。所以在第二和随后的表单不位于索引0开始 - 它们开始于索引1,然后索引2等。因此,该模型结合立即失败,你会得到一个空对象传递给控制器​​。

最简单的解决方案是迁移到一个单一的形式,这样的模型绑定可以访问合同对象的所有索引,然后使用额外的code控制器,以确定哪些提交按钮是pressed

我不能肯定这是最好的解决方案,但作为具有<一个href=\"http://stackoverflow.com/questions/8712398/multiple-forms-or-multiple-submits-in-a-page\">multiple形式和提交按钮是从视图的一个HTTP点更好,因为它减少了被发送到服务器的不必要的数据量。然而,最好是好的敌人,如果一个单一的形式运作...

Ok, I hope someone out there can help me out on this one (Thanks in advance!). I'm using MVC4.

My ContractsModel contains (among other things) a list of ContractModel(s). In my partial view, I loop though the list creating a form for each. So far so good. The issue is on postback. The 1st form always posts back fine. But the others (2, 3, 4, etc) always return null.

I've checked with debugging tools and confirmed that the rendered controls are appropriately named.

<select name="Contracts[0].OrganizationId" id="Contracts_0__OrganizationId">
<select name="Contracts[1].OrganizationId" id="Contracts_1__OrganizationId">
<select name="Contracts[2].OrganizationId" id="Contracts_2__OrganizationId">

I've also confirmed that client is indeed returning data to the server, but for some reason it does not seem to be getting attached back into the model that my ActionResult is expecting. Any ideas?

I've minimized my code for brevity.

Here are my models:

public class ContractsModel
{
    public ContractsModel()  
    {
        this.Contracts = new List<ContractModel>();

        this.OrganizationList = new List<SelectListItem>();
        this.ContractNumList = new List<SelectListItem>();
    }

    public string ParentProjectId { get; set; }
    // etc, etc .....

    public List<ContractModel> Contracts { get; set; }

    public List<SelectListItem> OrganizationList { get; set; }
    public List<SelectListItem> ContractNumList { get; set; }
}


public class ContractModel
{
    public string OrganizationId { get; set; }
    public string Organization { get; set; }
    public string ContractNumId { get; set; }
    public string ContractNum { get; set; }
}

Here is my Controller Action

[HttpPost]
public ActionResult _ContractsEdit(ContractsModel model)
{

    if (ModelState.IsValid) {
        //blah, blah, blah....
    }

    return PartialView("Index", ProjectModel);
}

Here is my Partial View

@model Manager.Models.ContractsModel

@for (int i = 0; i < Model.Contracts.Count(); i++)  
{
    var divId = "divContractsModelItem_" + (i + 1);
    var saveButtonId = "btnContractsEditSave_" + (i + 1);


    <div id = "@divId">  

        @using (Html.BeginForm("_ContractsEdit", "Projects", FormMethod.Post))
        {      
            <fieldset>
                <legend>General:</legend>

                <div>
                    <label>Contracting Organization:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].OrganizationId, new SelectList(Model.OrganizationList, "value", "text", Model.Contracts[i].OrganizationId))
                </div>

                <div>
                    <label>Contract Number:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].ContractNumId, new SelectList(Model.ContractNumList, "value", "text", Model.Contracts[i].ContractNumId))
                </div>

                <div>
                   <button id="@saveButtonId" type="submit">Save</button>
                </div>

            </fieldset>
        }
    </div> 

} 

解决方案

Since my comments helped you, I figured I would flesh them out as a full answer.

The problem with the model binding is that it does not allow you to skip array indexes - once one is skipped, it stops binding. Your page has multiple forms, one for each Contract. So the second and subsequent forms do not start at index 0 - they start at index 1 and then index 2 and so on. Thus, the model binding fails immediately and you get a null object passed into your controller.

The simple solution is to move to a single form so that the model binding has access to all the indexes of the Contract objects, and then use extra code in the controller to determine which submit button was pressed.

I'm not certain that is the best solution, though, as having multiple forms and submit buttons is better from an HTTP point of view, since it reduces the amount of unnecessary data that is being posted to the server. However, best is the enemy of good, and if a single form works...

这篇关于在PartialView MVC多种形式的回传返回null除了一日一上市的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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