【问题标题】:Best way to pass big List<T> from View to Controller将大 List<T> 从 View 传递到 Controller 的最佳方法
【发布时间】:2016-08-28 14:33:09
【问题描述】:

我正在开发一个包含列表的视图(选定的布尔值/ID 字符串/名称字符串/十进制值)。

在此视图中,用户将选择一些项目并提交表单以将它们保存在数据库中。但是这个 List/ 大约有 2000 个项目,而且速度非常慢。

我的控制器:

public ActionResult Create(List<MyClass> list) {
    foreach (var item in list) {
        if (item.Checked) {
            // something
        }
    }
}

我的观点:

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

    @* TH /HTML *@

    @for (int r = 0; r < Model.Count(); r++)
    {
        <tr class="tr-clickable">
            @Html.HiddenFor(i => i[r].ID_User)
            <td>@Html.CheckBoxFor(i => i[r].Checked)</td>
            <td>@Html.DisplayFor(i => i[r].Anything1)</td>
            <td>@Html.DisplayFor(i => i[r].Anything2)</td>
            <td>@Html.DisplayFor(i => i[r].Value)</td>
        </tr>
    }

    @* HTML *@

    <div class="control-group margin-top-20 pull-right">
        <div class="controls">
            <input type="submit" class="btn btn-default" value="Send Form" />
        </div>
    </div>
}

有没有更好的方法在我的控制器中接收此列表?我一直在考虑通过jQuery-ajax发送列表并一一保存。

你们怎么看?

【问题讨论】:

  • 用户必须选择 2000 个项目吗?那是糟糕的用户体验。
  • 您正在检查发送的项目是否被选中。客户是否可以只发送选定的项目?我想这会显着减少元素。我认为一个一个发送会更慢。
  • 从 2000 项中选择从使用经验来看有点麻烦请查看此链接以了解如何将 ilst 传递给控制器​​haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
  • @Shyju 不,用户选择大约 20/30/100 或所有项目。

标签: c# asp.net-mvc model-view-controller view controller


【解决方案1】:

我认为,您的问题不在于“传递列表”,而在于“逐个保存选定的列表项”。将 2k 列表从视图发送到控制器并没有那么重(嗯,确实如此,但它的工作速度应该不会太慢)。但是,如果您对 N 个选定项目执行 N 个数据库操作,这就是您的瓶颈所在。

你有两个选择:

  1. 用户选择后立即保存所选项目。
  2. 通过至少使用单个事务来保存项目来优化您的数据库操作。

【讨论】:

  • 好的,但是我怎样才能发送 List 只包含选定的对象?
  • @AntônioFilho 你可以使用 jQuery:$("#select-list").val() 如果你想在表单提交时发送所有选择的值,或者你可以使用 ajax 在用户选择项目时一一发送值。
  • 对不起,我有点困惑。我必须做这样的事情吗? " $.ajax({ url: '@Url.Action("MyAction", "MyController")', 类型: 'POST', 数据: $("#select-list").serialize(), 成功: 函数 (结果) { alert('ok'); } });"
  • @AntônioFilho 是的,类似的。获取值,然后使用 Ajax 传递它们。但我建议在用户选择它们时考虑保存值。
  • @AntônioFilho 它对你有用吗?你还需要帮助吗?
【解决方案2】:

正如其他人所提到的,我将首先探索改变整个用户体验。如果您确实遇到用户需要一一选择大量记录的情况,我会使用AJAX并在选择时将它们一一提交给Web api控制器。

这具有逐步保存进度并允许用户离开屏幕的额外好处。

【讨论】:

  • 根据选择我通过ajax发送记录,是吗?
  • @AntônioFilho 正确,当用户从列表中选择一个项目时,您可以执行对服务器的 ajax 调用。如果您只需要更新服务器上的“选定”布尔值,那么我建议只发送该字段的标识符和新值,而不是整个对象。
  • 知道了,但这不是我的情况。因为我需要在提交事件时发送整个对象。我无法在每次点击时一一进行,但我可以在提交时一一进行...
【解决方案3】:

我的解决方案是在 jQuery Ajax 中:

    $('input[type="button"][data-submit]').click(function () {

        if (confirm('Anything?')) {

            var array = [];

            $('#table > tbody > tr').each(function () {
                var $tr = $(this);
                var usid = $tr.find('[data-usid]').val();
                var irvlr = $tr.find('[data-irvlr]').val();
                array.push({
                    User: usid,
                    Value: irvlr
                });
            });

            if (array.length > 0) {
                $.ajax({
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    type: 'POST',
                    url: '@Url.Action("MyAction", "MyController")',
                    data: JSON.stringify({ 'list': array }),
                    success: function (result) {
                        window.location.href = result.url;
                    },
                    error: function (ex) {
                    }
                });
            }
            else {
                alert('No items selected.');
            }

        }

    });

谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多