0

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

该视图使用视图模型来合并几个 SQL 表。作为该视图模型的一部分,List类型的集合对象BankListAgentId用于存储与特定客户端相关的所有代理 ID。为了正确发布和编辑集合对象中的项目,我关注了Steve Sanderson关于 ASP MVC 中的可变长度对象的博客文章。

这个过程非常适合代理 ID,但是一旦用户点击“保存”,状态代码就会全部为空。

这是视图中的代码

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

这是视图模型

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

这是从控制器到编辑页面的原始 POST

    public ActionResult Edit(int id)
    {
        BankListMaster banklistmaster = db.BankListMaster.Find(id);
        BankListViewModel viewModel = new BankListViewModel();
        viewModel.BankName = banklistmaster.BankName;
        viewModel.LastChangeDate = banklistmaster.LastChangeDate;
        viewModel.LastChangeOperator = banklistmaster.LastChangeOperator;

        List<BankListAgentId> agentId = (from c in db.BankListAgentId
                                         where c.ID == id
                                         select c).ToList();

        foreach (var bankListAgentId in agentId)
        {
            string value = bankListAgentId.FixedOrVariable.Trim();
            if (value.Equals("Fixed"))
            {
                viewModel.Fixed.Add(bankListAgentId);
            }
            else
            {
                viewModel.Variable.Add(bankListAgentId);
            }
        }

        viewModel.Attachments = (from c in db.BankListAttachments
                                 where c.ID == id
                                 select c).ToList();

        SelectList tmpList = new SelectList(new[] { "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NA", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "US", "VT", "VI", "VA", "WA", "WV", "WI", "WY" });
        ViewBag.StateCodeList = tmpList;

        ViewBag.ID = new SelectList(db.BankListAgentId, "ID", "FixedOrVariable", banklistmaster.ID);
        return View(viewModel);
    }

public partial class BankListAgentId
{
    public string AgentId { get; set; }
    public int ID { get; set; }
    public string FixedOrVariable { get; set; }
    public string StateCode { get; set; }

    public virtual BankListMaster BankListMaster { get; set; }
}
4

2 回答 2

0

问题是您使用的是像 EditorTemplate 这样的局部视图。Partial Views 和 EditorTemplates 是不同的。您可以将局部视图视为包含一些额外内容的服务器端。

因此,这里的问题是您将不同的模型传递给部分,而不是在父类中使用。

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

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

我建议不要使用局部视图,而是使用 EditorTemplate,因为这是它们旨在处理的内容(在对象中呈现类型),并且它们会自动处理集合。

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

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

于 2013-04-03T23:01:41.643 回答
0

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

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

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

于 2013-04-03T23:03:06.020 回答