You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Razor @foreach多表单异步提交删除购物车项问题求助

问题根源梳理
  • 参数拼写错误:后端接口接收参数名为cartId,你修改后的JS代码传参写为cardId,参数无法绑定,后端接收不到合法参数导致执行异常
  • 缺少Razor Pages防伪令牌验证:ASP.NET Core Razor Pages默认开启Post请求防伪校验,你的AJAX请求未携带防伪令牌,后端直接返回400空响应,浏览器将空响应当做XML解析就会抛出你遇到的XML解析错误
  • 事件绑定逻辑错误:你之前将onsubmit事件绑定写在onclick回调里,第一次点击仅完成事件绑定,不会触发提交逻辑,所以点击无响应
  • 空响应解析问题:你的删除接口没有返回任何响应内容,前端AJAX拿到空内容无法正常处理
优化后的完整代码

1. Razor视图代码

首先在页面任意位置(比如最顶端)加全局防伪令牌:

@Html.AntiForgeryToken()

购物车循环部分简化,不需要每个项单独套form,直接用data属性存储参数即可:

@foreach (var item in Model.Items)
{
    <div class="cart-item" id="cart_item_@item.Id">
        <h4 class="text-left text-body">
            @item.Price.ToString("c")
            <button class="btn btn-sm btn-remove" title="Trash" 
                    data-cart-id="@Model.Id" 
                    data-cart-item-id="@item.Id">
                <i style="font-size:large" class="text-warning icon-Trash"></i>
            </button>
        </h4>
    </div>
}

2. JavaScript代码

采用事件委托绑定删除事件,不需要给每个按钮单独绑定,动态刷新的购物车项也能自动生效:

<script>
// 全局绑定删除按钮点击事件,支持动态加载的元素
$(document).on('click', '.btn-remove', function() {
    const cartId = $(this).data('cart-id');
    const cartItemId = $(this).data('cart-item-id');
    const removeUrl = "/sales/cart?handler=RemoveItem";

    $.post({
        url: removeUrl,
        headers: {
            // 携带防伪令牌
            "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val()
        },
        data: {
            cartId: cartId,
            cartItemId: cartItemId
        }
    }).done(function() {
        // 删除成功后刷新购物车弹窗,和你原有逻辑保持一致
        $.ajax({
            url: "/sales/cart?handler=CartPartial",
            success: function (data) {
                $("#exampleModal .modal-dialog").html(data);
                $("#exampleModal").modal("show");
            }
        });
    }).fail(function(err) {
        console.error('删除失败:', err);
        alert('删除商品失败,请重试');
    });
});
</script>

3. 后端代码调整

给删除接口增加返回值,避免空响应导致的解析错误:

public async Task<IActionResult> OnPostRemoveItemAsync(int cartId, int cartItemId)
{
    try
    {
        await _cartRepository.RemoveItem(cartId, cartItemId);
        return new JsonResult(new { success = true });
    }
    catch (Exception ex)
    {
        return new JsonResult(new { success = false, msg = ex.Message });
    }
}
补充说明

如果你要继续使用form方案,只需要调整事件绑定逻辑即可:不要在onclick里绑定onsubmit,直接在onclick里处理提交逻辑,同时记得在每个form里加@Html.AntiForgeryToken(),FormData会自动包含这个令牌,不需要额外处理。

内容的提问来源于stack exchange,提问作者Malawby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:54:05