ASP MVC模型列表<object>在POST操作中返回Empty </object>

时间:2014-05-22 13:18:08

标签: c# asp.net-mvc

我遇到了这个问题,我很难解决。我正在创建一个页面,向用户显示项目列表(产品类型)。每个项目旁边都有一个下拉列表,以便用户可以进行适当的选择以创建映射。选择后,用户提交表单,值将写入数据库。

问题在于,当提交时,我没有得到任何价值。具体来说,POST操作返回的模型中的“Mappings”为空。 GET行动很好。以下是我所写内容的精髓:

型号:

public class ProductTypeMappingViewModel
{
    //this is empty in the POST object
    public List<ProductTypeMapping> Mappings { get; set; }

    public ProductTypeMappingViewModel()
    {
        Mappings = new List<ProductTypeMapping>();
    }

    public ProductTypeMappingViewModel(string db)
    {
        //use this to populate 'Mappings' for GET action
        //works fine
    }

    public void UpdateDB()
    {
        //to be called on the object
        //returned from POST action
        foreach(var mapping in Mappings)
        {
        //Mappings is always empty after POST
        //Suppose to add to db
        }
    }
}

public class ProductTypeMapping
{
    public string ProductTypeName { get; set; }
    public int SelectedStandardProductTypeKey { get; set; }
    public SelectList StandardProductTypes { get; set; }

    public ProductTypeMapping() 
    {
        StandardProductTypes = new SelectList(new List<SelectListItem>());
    }

    public int GetSelectedProductTypeKey() { //return selected key}

    public string GetSelectedProductTypeName() { //return selected name} 
}

查看:

@model CorporateM10.Models.ProductTypeMappingViewModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @Html.ValidationSummary(true)

        <table class="table">
            @foreach (var dept in Model.Mappings)
            {
            <tr>
                <td>
                    @Html.DisplayFor(model => dept.ProductTypeName, new { })
                </td>
                <td>
                    @Html.DropDownListFor(model => dept.SelectedStandardProductTypeKey, dept.StandardProductTypes, "(Select Department)", new { })
                </td>
            </tr>
            }
        </table>

        <div>
            <input type="submit" value="Save" class="btn btn-default" />
        </div>
    </div>
}

非常感谢任何见解。

2 个答案:

答案 0 :(得分:7)

foreach此处导致最终HTML中的select元素具有不正确的name属性。因此,没有任何内容发布到服务器。将其替换为for循环:

<table class="table">
    @for (int i=0; i<Model.Mappings.Count; i++)
    {
    <tr>
        <td>
            @Html.DisplayFor(model => model.Mappings[i].ProductTypeName, new { })
        </td>
        <td>
            @Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey, model.Mappings[i].StandardProductTypes, "(Select Department)", new { })
        </td>
    </tr>
    }
</table>

答案 1 :(得分:3)

正如@Andrei所说,问题依赖于name属性。 但是为了给他的答案添加一点点,这里是请求中的参数名称,默认模型绑定器对你的案例有所期望。

Mappings[0].SelectedStandardProductTypeKey
Mappings[1].SelectedStandardProductTypeKey
Mappings[2].SelectedStandardProductTypeKey

...

编号没有任何中断,即:

Mappings[0].SelectedStandardProductTypeKey
Mappings[2].SelectedStandardProductTypeKey

由于缺少Mapping [1] ......

,因此无法工作

当你像这样使用下拉助手时: @Html.DropDownListFor(model => dept.SelectedStandardProductTypeKey, dept.StandardProductTypes, "(Select Department)", new { })

它生成一个名为=&#34; SelectedStandardProductTypeKey&#34;的输入。 (你需要它是Mappings [0] .SelectedStandardProductTypeKey)

如果您使用for循环并使用下拉帮助器,如下所示: @Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey
您将获得具有正确名称的输入。

请求中的模型绑定器无法在模型中找到属性的任何参数,它将忽略,这就是为什么Mappings属性在您的情况下为空。

这里有两个很好的资源来解释所有这些(并且提供了替代方法来表示可能有用的集合,如果你不能在for循环中生成一个没有中断的编号索引):
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx