MVC 4:视图没有使用来自列表的正确数据呈现.模型中

本文关键字:数据 模型 列表 视图 MVC | 更新日期: 2023-09-27 18:03:13

有一个相当棘手的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; }
}

这是我的razor视图的一个片段

<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实际上是从模型的列属性中删除的。再次调试剃须刀时,"2"列不见了。

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

有人知道会发生什么吗?

此外,当我单击add时,我希望在我的html表中有另一行类似"NEW_COLUMN_NAME"的内容。它确实添加了另一行,但它似乎复制了最后一行的数据,而不是从我的控制器中放置值。

再次,我的控制器会说,我有一个新的ColumnConfig与"NEW_COLUMN_NAME"在它的调试,但实际得到呈现给客户端的页面有以前的ColumnConfig的数据在它。这真让人抓狂!

MVC 4:视图没有使用来自列表的正确数据呈现.模型中

我知道这是一个旧的帖子,但我有一个相同的问题。removeat()调用。找到解决办法了。我在. removeat()调用之前添加了这段代码。

ModelState.Clear();

假设:

  1. 你在某个地方有<form>标签,你没有给我们看。
  2. 你的表单做一个POST到ManageCustomColumns的动作。

请注意,您正在尝试根据Request.Form["Action"]的值确定要删除的列配置。这个表单字段在HTML中的位置?还要注意,您的值为remove-1的按钮称为RemoveBtn1,因此结果是您想要的值将在Request.Form["RemoveBtn1"]中。您可能需要一个名为"Action"的隐藏表单字段,并在按钮单击时使用Javascript使用按钮值填充该字段。