MVC Ajax在单击事件中发布到控制器

哈里普斯

单击复选框时,我试图使用Ajax发布到控制器。它应该更新现有对象。我的两个问题是:

  • 我无法成功调用控制器操作方法
  • 仅列表中的第一项具有单击事件

希望有人可以帮忙

使用ajax的单击事件

    $('#checkboxID').on('click', function () {
            $.ajax({
                url: '@Url.Action("Attending", "GuestBookings")',
                type: 'POST',
                data: JSON.stringify({
                    "cID": $(this).val('cID'), "eID": $(this).val('eID'), "check": $(this).is(':checked') ? 1 : 0
                }),
                success: function(result) {
                    alert("Succeeded post");
                },
                error: function(result) {
                    alert("Failed to post");
                }
            });
        });

控制器HttpPost

    [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Attending(string cID, string eID, string check)
        {
            if (ModelState.IsValid)
            {
                var guest = await _context.Guests
                                     .Where(g => g.CustomerId.ToString() == cID && g.EventId.ToString() == eID).FirstOrDefaultAsync();
                if (check == "0")
                {
                    guest.Attended = false;
                }
                else
                {
                    guest.Attended = true;
                }
                try
                {
                    _context.Update(guest);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {

                }
            }
            return Json(true);
        }

复选框

    <tbody>
            @foreach (var item in Model.GuestsBooked)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Surname)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.FirstName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Email)
                    </td>
                    <td>
                        @Html.CheckBoxFor(modelItem => item.Attended, new { @id = "checkboxID", @cID = item.Id, @eID = Model.Id })
                    </td>
                    <td>
                        @Html.ActionLink("Details", "Details", "Customers", new { id = item.Id }) |
                        @Html.ActionLink("Unbook", "Delete", "GuestBookings", new { id = item.Id, eventId = Model.Id }) |
                    </td>
                </tr>
            }
        </tbody>
y州

我发现您的代码存在一些问题。

首先,在您的视图代码中,您正在循环内渲染表行。在表行中,您正在使用CheckBoxForhelper方法来呈现并绑定Attended属性值中的复选框但是,您正在使用重载,其中您要将匿名对象作为html属性传递,并且在那里将Id属性值传递checkboxID这意味着它会呈现checkboxIDId所有的复选框。ID值应唯一。如果您对多个元素使用相同的ID值,则该HTML无效。这也将导致您的jQuery click事件仅适用于集合中的第一项(在第一行表中呈现的复选框)。

让我们先解决这个问题。您可以使用另一个属性来连接jQuery click事件处理程序。例如,在这里我要添加一个名为的属性,ajaxupdate而不是Id

@Html.CheckBoxFor(modelItem => item.Attended, 
                                 new {  ajaxupdate="true", 
                                        @cID = item.Id, @eID = Model.Id })

进行此更改后,它将像这样呈现checkbox元素的HTML标记(为便于阅读,省略了某些属性)。这里的重要部分是ajaxupdate属性的存在

<input ajaxupdate="true" checked="checked" 
       cid="1" eid="2" name="item.Active" type="checkbox" >

现在连接click事件处理程序,我们可以使用此数据属性选择器。

$('[ajaxupdate="true"]').on('click', function () {
   // to do : code for ajax call
});

修复此问题后,我们将发现click事件至少是在执行事件处理程序代码时执行的。但是您会注意到,ajax调用从服务器收到400错误的请求响应。发生这种情况是因为您的操作方法已用ValidateAntiForgeryToken属性装饰当用此方法装饰操作方法时,框架将检查提交的请求数据,如果未找到有效的防伪令牌,则将其视为错误请求,并将发送400响应。

要解决此问题,您可以显式读取__RequestVerificationToken隐藏输入的值(由@Html.AntiForgeryToken()视图中方法调用生成),并将其发送到ajax请求标头中。

var t = $("input[name='__RequestVerificationToken']").val();

$.ajax({  url: '@Url.Action("Attending", "Home")',
          type: 'POST',
          headers:
                {
                    "RequestVerificationToken": t
                },
        //existing code for ajax
       })

另一种选择是删除ValidateAntiForgeryToken但是会影响安全性。”

现在,通过上述步骤,我们必须解决我们的400响应问题。现在您可能会收到500 Internal server error,这是因为您收到一些null引用错误,因为您的操作方法参数未正确与您期望的值绑定,并且LINQ查询可能返回了null对象,并且您尝试更新Attended属性该对象的值,而无需先检查它是否为NULL对象。

让我们首先修复客户端代码。在复选框的click事件处理程序内,该this表达式表示被单击的复选框元素。在您的剃刀代码中,您将cIDeID设置为元素的属性。因此,您应该阅读有关attrmethod的内容。另外,您不需要发送JSON字符串版本。只需将JavaScript对象作为data属性传递即可

因此,客户端代码的最终清理版本为

$(function () {

    $('[ajaxupdate="true"]').on('click', function () {
        var t = $("input[name='__RequestVerificationToken']").val();
        var $this = $(this);
        $.ajax({
            url: '@Url.Action("Attending", "GuestBookings")',
            type: 'POST',
            headers:
            {
                "RequestVerificationToken": t
            },
            data: {
                "cID": $this.attr('cID'),
                "eID": $this.attr('eID'),
                "check": $this.is(':checked') ? 1 : 0
            },
            success: function(result) {
                alert("Succeeded post");
                console.log(result);
            },
            error: function(xhr,status,errorThrown) {
                alert("Failed to post");
                console.log(errorThrown);
            }
        });
    });

});

我的另一个建议是在服务器端代码上使用正确的类型。您将string类型用作参数,然后ToString()调用数字属性进行比较(与Where子句中的谓词比较)。而不是这样做,而是使用适当的数字类型作为参数。

public async Task<IActionResult> Attending(int cID, int eID, int check)
{
    var guest = await _context.Guests
                              .Where(g => g.CustomerId == cID 
                                       && g.EventId == eID)
                              .FirstOrDefaultAsync();
    if(guest!=null)
    {
       guest.IsActive = check == 0;
       try
       {
           _context.Update(guest);
           await _context.SaveChangesAsync();
       }
       catch (Exception ex)
       {
          // Make sure to log the exception and not leak the ToString version to client.
          return Json(new { status = false, message = ex.ToString() });
       }
       return Json(new { status = true, message = "Updated" });
    }
    return Json(new { status = false, message = "Customer not found!" });
}

在上面的代码中,我将具有状态和消息属性的JSON对象返回给客户端。对于异常用例,我将ToString()在message属性中发送异常版本。仅当您希望在客户端(主要是在开发过程中)看到它时,才应该这样做。当您将其运送到生产环境时,您不想将此信息泄漏给客户。而是记录它。

successajax调用处理程序内部,您可以根据需要检查statusmessage属性。

success: function(result) {
    alert(result.message);                   
},

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

ajax不会将文件发布到控制器mvc

如何在MVC控制器中发布模态值

Ajax发布到ASP.net MVC控制器-对象属性为null

如何使用AJAX将数据发布到ASP.NET MVC控制器?

将数组和表单数据发布到控制器-MVC Ajax

ASP.NET 5 / MVC 6 Ajax将模型发布到控制器

Ajax中的日期将数据发布到MVC控制器

ajax 发布到 MVC 控制器失败,400 错误请求

Ajax发布不会将任何数据传递到MVC控制器

使用Ajax将JSON数据发布到MVC控制器

jQuery Ajax发布到MVC控制器不起作用(返回null)

将 AJAX 字符串发布到 MVC 控制器

MVC将子模型发布到控制器

将数据从 DropDownList 发布到 MVC 控制器

AJAX发布数据在控制器MVC中为空

ASP.NET MVC从同一控制器发布到控制器的操作

数组到带有Ajax的MVC控制器

多个ajax数据到Spring MVC控制器

MVC Ajax 阻止重定向到动作控制器

.net核心3.1将对象的ajax列表发布到MVC控制器,没有数据到达

如何在MVC中使用Ajax调用打开弹出窗口并将数据同时发布到控制器

AJAX发布到ASP.NET MVC 6控制器的操作方法和参数为null

如何使用Ajax将文件和表单数据一起发布到MVC控制器?

Asp.net 核心 mvc ajax 发布到具有多个参数的控制器返回错误请求

JQUERY ajax将JSON发布到C#MVC控制器,但是传入的数据为null

我正在使用Ajax发布到Mvc中的控制器,但是我的var在foreach中重置为null

使用 FormData MVC 将文件和列表发布到 MVC 控制器

数据不在MVC控制器中发布select2列表框Mvc

在MVC控制器中订阅事件