被发布的ID始终是表格第一行的Id

时间:2017-03-22 17:28:40

标签: c# asp.net-mvc razor

MVC 5项目。使用模态视图。模态有2个部分。顶部是一个带有“添加”按钮的下拉列表。下面是主表,具有行删除功能(如下所述)。它应该如何工作:如果用户点击“添加”,该条目将进入表格。这很好用。我正在尝试使用行特定的删除功能。让我来描述一下这个问题......

我基本上有一个包含许多项目的表格,每行都有一个删除按钮。这些行就是这样创建的......

<table class="table table-striped">
    <tr>
        <th>
           @Html.DisplayNameFor(model => model.Filter.Filter1)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
      {
         <tr>
            <td>
               @Html.DisplayFor(modelItem => item.Filter.Filter1)
            </td>
         <td>
         @using (Html.BeginForm("DeleteFromModal", "carColorsFilters", FormMethod.Post))
            {
                <b>@item.Id</b>
                @Html.Hidden("id", item.Id)
                @Html.Hidden("carColorId", (Int32)ViewBag.carColorId)
                <input class="btn btn-primary" type="submit" value="Delete" />
            }
          </td>
        </tr>
    }
</table>

我的帖子操作被定义为......

        public ActionResult DeleteFromModal(int id, int carColorId)
    {
        carColorsFilter carColorsFilter = db.carColorsFilters.Find(id);
        db.carColorsFilters.Remove(carColorsFilter);
        db.SaveChanges();


        ViewBag.carColorId = carColorId;
        ViewBag.FilterId = new SelectList(db.Filters, "Id", "Filter1");
        var carColorsfilters = db.carColorsFilters
                .Where(a => a.carColorId == carColorId)
                .Include(a => a.carColor)
                .Include(a => a.Filter);
        return View("_Index", carColorsfilters.ToList());
    }

此视图显示为模式弹出窗口。

当模态首次加载时,我仔细检查了HTML隐藏字段的ID(使用View Source),它们都是正确的。但是,当我点击删除按钮时,无论行如何,第一行的ID总是传递给动作。

然后,如果我再次立即检查HTML隐藏字段,ID的所有隐藏字段都是EXACT SAME,这是ORIGINAL第一行的ID(在原始删除点击中删除了),因此出错发生。

为什么会发生这种情况?

以下是模态操作的源代码......

    <script type="text/javascript">


    $(function () {
        $.ajaxSetup({ cache: false });

        $("a[data-modal]").on("click", function (e) {
            // hide dropdown if any (this is used wehen invoking modal from link in bootstrap dropdown )
            //$(e.target).closest('.btn-group').children('.dropdown-toggle').dropdown('toggle');

            $('#myModalContent').load(this.href, function () {
                $('#myModal').modal({
                    /*backdrop: 'static',*/
                    keyboard: true
                }, 'show');
                bindForm(this);
            });
            return false;
        });
    });

    function bindForm(dialog) {
        $('form', dialog).submit(function () {
            $.ajax({
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) {
                    if (result.success) {
                        $('#myModal').modal('hide');
                        $('#replacetarget').load(result.url); //  Load data from the server and place the returned HTML into the matched element
                    } else {
                        $('#myModalContent').html(result);
                        bindForm(dialog);
                    }
                }
            });
            return false;
        });
    }
</script>

3 个答案:

答案 0 :(得分:0)

您的问题可能出在以下两行:

@Html.Hidden("id", item.Id)
@Html.Hidden("carColorId", (Int32)ViewBag.carColorId)

它们处于循环中,隐藏字段的名称被设置为静态值(id和carColorId)。这会在每次迭代时生成具有相同名称的隐藏字段,从而导致您的问题出现在&#34; first&#34; id始终传递给动作。作为旁注,这是无效的,因为元素ID对于整个文档而言是唯一的。无论如何,我建议你改变一下:

@* Switch to a for loop to allow using the iterator variable to create
   unique names and ids for the fields *@
@for (var i = 0; i < Model.Count; i++)

@Html.HiddenFor(m => m[i].Id)
@Html.HiddenFor(m => m[i].CarColorId) 

我假设您的模型实际上是IEnumerable或类似的,并且CarColorId是模型中第二个隐藏字段的属性名称 - 您希望将其填入控制器,而不是使用ViewBag。

希望有所帮助。

答案 1 :(得分:0)

Sleeyuen是的,重复的名称导致了这个问题,所以我个人会采取不同的方法。

页面上可能有一个名为隐藏的表单。

@using (Html.BeginForm("DeleteFromModal", "carColorsFilters", FormMethod.Post, new { name = "deleteFrm", id = "deleteFrm" }))
{
    @Html.Hidden("id", item.Id)
    @Html.Hidden("carColorId", (Int32)ViewBag.carColorId)
}

您的删除按钮应该只有button种类型,并且要将ID删除为data-属性。

<input class="btn btn-primary deleteCarColorBtn" type="button" value="Delete" data-delete-id="item.id" data-car-color-id="(Int32)ViewBag.carColorId" />

然后在按钮的点击事件中,您可以阅读deleteid,将其传递给您的表单并提交。

var deleteId = $(".deleteCarColorBtn").data('deleteId');
var carColorId = $(".deleteCarColorBtn").data('carColorId');
$("#id").val(deleteId);
$("#carColorId").val(carColorId);
$("#deleteFrm").submit();

答案 2 :(得分:0)

感谢@StephenMuecke的正确答案。

一旦我做了ModelState.Clear(),它似乎工作得更好!

如果您能告诉我如何奖励您答案,请告诉我。 :)