【问题标题】:ASP.net core AntiForgeryToken issue : data doesn't bind to modelASP.net 核心 AntiForgeryToken 问题:数据未绑定到模型
【发布时间】:2022-02-22 16:27:05
【问题描述】:

我有一个使用谷歌时间线图表的 asp.net 核心预订系统的工作项目。当您单击图表时,会弹出带有部分视图的模式弹出窗口以输入数据。 Javacript 在保存按钮上有一个单击事件以将数据发送到控制器。控制器验证数据并将部分视图发送回 javascript,然后将其发送回模式弹出窗口。我在视图上有两个标志,如果设置为 true,javascript 会隐藏弹出窗口。这一切都有效,直到我用[ValidateAntiForgeryToken]装饰控制器

我的代码如下


启动:

services.AddAntiforgery(options => {
    options.HeaderName = "RequestVerificationToken";
});

Javascript:

(function() {
        var PlaceHolderElement = $('#PlaceHolderHere');
        //create popup save
        PlaceHolderElement.on('click', '[data-save="modal"]', function(event) {
            event.preventDefault();
            var form = $(this).parents('.modal').find('form');
            var token = $("input[name='__RequestVerificationToken']").val();
            var actionUrl = form.attr('action');
            var sendData = form.serialize();
            $.ajax({
                type: 'POST',
                url: actionUrl,
                data: sendData,
            }).done(function(data1) {
                var newBody = $('.modal-body', data1);
                PlaceHolderElement.find('.modal-body').replaceWith(newBody);
                var isValid = newBody.find('[name="IsValid"]').val() === 'True';
                var isValid2 = newBody.find('[name="BookingFree"]').val() === 'True';
                if (isValid && isValid2) {
                    PlaceHolderElement.find('.modal').modal('hide');
                    location.reload();
                }
            })
})

控制器:

[HttpPost]
public IActionResult EditBooking(BookingViewModel model) {

  if (ModelState.IsValid) {
    ... other code
  }
}

当我用 [ValidateAntiForgeryToken] 装饰控制器并将 jarvascript 更改为

data: {
    model: sendData,
    __RequestVerificationToken: token,
}

验证有效,但模型为空!如果我将模型声明为字符串,那么我会得到一个字符串。

如果我在 headers: 中发送令牌,则令牌验证失败

我需要模型中的数据才能让 ModelState 设置 IsValid

【问题讨论】:

  • 您好,.serialize() 默认将表单数据与 __RequestVerificationToken 值一起传递。 Startup.cs 中的AddAntiforgery 也没用。你能分享你的html代码吗?
  • 谢谢,我已经从 StartUp.cs 中删除了 AddAntiforgery 并将 @Html.AntiForgeryToken() 添加到我的视图页面,它现在可以工作了。以前试过这个,但失败了。再次感谢您
  • 我在下面分享了一个答案。请检查。

标签: javascript asp.net ajax asp.net-core antiforgerytoken


【解决方案1】:

1..serialize()默认将表单数据与__RequestVerificationToken值一起传递。

2.当您使用带有method="post" 和标签助手的表单元素时,它将动态生成表单内name="__RequestVerificationToken" 的令牌输入。但是如果你为<form action="/url" method="post"></form>这样的表单指定action属性,它将不会生成令牌输入。

因此,如果您指定了action 属性,则需要在表单中使用@Html.AntiForgeryToken() 手动添加令牌输入:

<form action="/url" method="post">
     @Html.AntiForgeryToken()
     //....
</form>

您可以遵循的简单工作演示:

查看:

<form asp-action="EditBooking" asp-controller="Home" method="post">
    <input asp-for="Name" />
    <input type="button" onclick="PostForm()" value="Post" />
</form>

@section Scripts
{
    <script>    
        function PostForm() {
            //var token = $("input[name='__RequestVerificationToken']").val();
            var actionUrl = $('form').attr('action');
            var sendData = $('form').serialize();
            console.log(sendData)
            $.ajax({
                type: 'POST',
                url: actionUrl,
                data: sendData,
            }).done(function(data1) {                                
            })
}
    </script>
}

并且无需添加以下代码:

services.AddAntiforgery(options => {
    options.HeaderName = "RequestVerificationToken";
});

【讨论】:

    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 2018-06-22
    • 2017-03-03
    • 2012-07-15
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多