MVC 4:使用List<>中的正确数据不呈现视图在模型中

时间:2015-07-17 22:19:30

标签: c# asp.net asp.net-mvc asp.net-mvc-4 razor

有一个相当棘手的ASP.NET MVC错误(使用MVC4)。我试图删除代码,以使这个例子尽可能清楚

我有一个模特

//this is the mvc model
public class CustomColumnConfiguration //stripped down to the "problem" property only
{
    public CustomColumnConfiguration()
    {
        Columns = new List<ColumnConfig>();
    }

    public List<ColumnConfig> Columns { get; set; }
}


//MVC model contains a list of these
public class ColumnConfig
{
    public ColumnConfig()
    {
        Name = "";
        Alias = "";
        Order = 0.0;
    }

    public string Name { get; set; }
    public string Alias { get; set; }
    public double Order { get; set; }
    public bool IsEnabled { get; set; }
}

这是我剃刀视图中的一个片段

<tbody>
@for (int i = 0; i < Model.Columns.Count; i++)
{
    <tr>
        <td>Column @(i+1)</td>
        <td>@Html.TextBoxFor(x => x.Columns[i].Name)</td>
        <td>@Html.TextBoxFor(x => x.Columns[i].Alias)</td>
        <td>@Html.TextBoxFor(x => x.Columns[i].Order)</td>
        <td>@Html.CheckBoxFor(x => x.Columns[i].UseRange)</td>
        <td><button name="RemoveBtn@(i)" class="btn btn-danger submit-action" type="submit" value="remove-@(i)"><i class="icon-remove icon-white"></i></button></td>
    </tr>
}
</tbody>
//...
@Html.Hidden("Action")

以下javascript负责将表单中的“action”输入设置回控制器,以便我知道要删除哪个索引:

$(document).ready(function () {
    $(".submit-action").on("click", function (e) {
        var $this = $(this);
        $("#action").val($this.val());
    });
});

GET和POST控制器代码:

public ActionResult ManageCustomColumns()
{
    CustomColumnConfiguration model = GetConfiguration(); //this works  
        return View(model);
}

[HttpPost]

public ActionResult ManageCustomColumns(CustomColumnConfiguration model)
{
    var action = Request.Form["Action"];
    if (action.Equals("SaveIndexConfiguration", StringComparison.CurrentCultureIgnoreCase))
    {
        this.AlertSuccess("Configuration Saved");
        SetConfiguration(model); //this works
    }
    else if(action.StartsWith("remove",StringComparison.CurrentCultureIgnoreCase))
    {
        var indexToRemove = int.Parse(action.Split('-')[1]);
        model.Columns.RemoveAt(indexToRemove);
    }
    else if (action.StartsWith("add", StringComparison.CurrentCultureIgnoreCase))
    {
        model.Columns.Insert(0, new ColumnConfig() { Name = "NEW_COLUMN_NAME", Alias = "New Column Alias" });
    }

    return View(model);

}

如果我有一个包含列配置1,2,3,4的页面。我可以单击第2列旁边的“删除”按钮,在VS中调试代码时,我看到名为“2”的ColumnConfig是实际上从模型的Columns属性中删除了。再次调试剃刀时,“2”列就消失了。

但是,在IE和Chrome中100%的一致性,我看到的行为是1,2,3仍然存在,它只是删除了最后一个(4)。这与我在调试器中看到的完全不一致。我不是MVC的新手,但这必须是我见过的最神奇的错误之一。

有没有人知道会发生什么?

更新 此外,当我点击添加时,我希望在我的html表格中有另一行包含“NEW_COLUMN_NAME”之类的内容。它会添加另一行,但它似乎复制了最后一行的数据,而不是从我的控制器中输入值。

同样,我的控制器会在调试时说我有一个新的ColumnConfig,其中包含“NEW_COLUMN_NAME”,但实际呈现给客户端的页面中包含之前的ColumnConfig数据。这令人抓狂!

2 个答案:

答案 0 :(得分:2)

我知道这是一个旧帖子,但我在.RemoveAt()调用时遇到了同样的问题。找到了解决方案。我在.RemoveAt()调用之前添加了这段代码。

ModelState.Clear();

答案 1 :(得分:1)

假设:

  1. 您在某些地方找不到<form>个标签。
  2. 您的表单会对ManageCustomColumns操作发布POST。
  3. 请注意,您正在尝试根据Request.Form["Action"]的值确定要删除的列配置。 HTML中的此表单字段在哪里?另请注意,值为remove-1的按钮名为RemoveBtn1,因此结果是所需的值将位于Request.Form["RemoveBtn1"]中。您可能需要一个名为&#34; Action&#34;的隐藏表单字段。并在按钮上单击使用Javascript以使用按钮值填充该字段。