在编辑页面上的DropDownListFor将空值传递给POSTBACK上的控制器

时间:2013-04-03 21:56:31

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 postback html.dropdownlistfor

我有一个ASP MVC3项目,它在编辑页面中使用了局部视图。它将正确的值加载到DropDownListFor中,但是在POST BACK上,项突然为空。

视图使用视图模型来合并一些SQL表。作为该视图模型的一部分,类型为List的{​​{1}}集合对象用于存储与特定客户端相关的所有代理Id。为了正确地POST和编辑集合对象中的项,我跟着Steve Sanderson's blog post关于ASP MVC中的变长对象。

此过程适用于代理ID,但是一旦用户点击“保存”,状态代码全部为空。

以下是视图中的代码

BankListAgentId

这是部分

@model Monet.ViewModel.BankListViewModel

@using (Html.BeginForm())
{
    <fieldset>
        <legend>Stat(s) Fixed</legend>
        <table id="fixedRows">
            <tr>
                <th>State Code</th>
                <th>Agent ID</th>
                <th></th>
            </tr>
            @foreach (var item in Model.Fixed)
            {
                if (!String.IsNullOrWhiteSpace(item.AgentId))
                {
                    @Html.Partial("FixedPartialView", item) 
                }
            }
        </table>
        <br />
        @Html.ActionLink("Add another", "BlankFixedRow", null, null, new { id = "addFixed" })
    </fieldset>
}

这是视图模型

@model Monet.Models.BankListAgentId


@using (Html.BeginCollectionItem("Variable"))
{
    <tr>
        <td>
            @Html.DropDownListFor(model => model.StateCode,
                (SelectList)ViewBag.StateCodeList, Model.StateCode)
        </td>
        <td>
            @Html.EditorFor(model => model.AgentId)
            @Html.ValidationMessageFor(model => model.AgentId)
        </td>
        <td>
        <a href="#" onclick="$(this).parent().remove();" style="float:right;">Delete</a></td>
    </tr>
}

以下是来自控制器的编辑页面的原始POST

public class BankListViewModel
{
    public int ID { get; set; }
    public string BankName { get; set; }
    public string LastChangeOperator { get; set; }
    public Nullable<System.DateTime> LastChangeDate { get; set; }

    public List<BankListAgentId> Fixed { get; set; }
    public List<BankListAgentId> Variable { get; set; }
    public List<BankListAttachments> Attachments { get; set; }

    public BankListViewModel()
    {
        //Initialize Fixed and Variable stat Lists
        Fixed = new List<BankListAgentId>();
        Variable = new List<BankListAgentId>();

        Models.BankListAgentId agentId = new BankListAgentId();

        for (int i = 0; i < 5; i++)
        {
            Fixed.Add(agentId);
            Variable.Add(agentId);

        }

        //Initialize attachment Lists
        Attachments = new List<BankListAttachments>();
        Attachments.Add(new BankListAttachments());
    }
}

2 个答案:

答案 0 :(得分:0)

问题是你正在使用像EditorTemplate这样的Partial视图。部分视图和EditorTemplates是不同的。您可以将局部视图视为服务器端包含一些额外的东西。

所以,这里的问题是你将一个不同的模型传递给部分,而不是在父类中使用。

@foreach (var item in Model.Fixed)
{
    if (!String.IsNullOrWhiteSpace(item.AgentId))
    {
        @Html.Partial("FixedPartialView", item) 
    }
}

当您提交模型时,部分视图中的帮助程序会将代码呈现为模型是固定的,因此它会错误地格式化并命名部分中的项目。在这种情况下,默认模型绑定器不知道“item”位于名为“Fixed”的集合中,因为您已经通过遍历foreach循环并仅从包含的项目中重新删除了该上下文。

我建议您使用EditorTemplate而不是使用局部视图,因为这是它们设计用来处理(在对象中呈现类型),它们会自动处理集合。

或者,如果您希望渲染部分,则不要传入子模型,只是让它从父级渲染。否则,您将需要做很多工作以确保在部分内部具有正确的命名。

或者,如果您只需要发布此项目集合,那么您可以确保您的发布操作接受IEnumerable<Fixed>而不是您的父模型。

答案 1 :(得分:0)

您可能希望尝试使用编辑器模板,而不是在循环中注入部分内容。

    @foreach (var item in Model.Fixed)
    {
        if (!String.IsNullOrWhiteSpace(item.AgentId))
        {
            @Html.EditorFor(item => item, "FixedPartialView") 
        }
    }

然后将FixedPartialView.cshtml放入适当的EditorTemplates文件夹中。我相信,绑定对于框架来说会更加直观。