jQuery 没有表单的 AJAX 发布 ValidateAntiForgeryToken 到 MVC 操作方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17857850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AJAX Posting ValidateAntiForgeryToken without Form to MVC Action Method
提问by Jammer
I've been looking at examples of how to do this on SO and as far as I can tell I've tried all the examples I can find with no success so far. I've tried altering some of the implementations to my scenario but this has thus far failed as well.
我一直在查看如何在 SO 上执行此操作的示例,据我所知,到目前为止,我已经尝试了所有可以找到的示例,但都没有成功。我已经尝试将一些实现更改为我的场景,但到目前为止这也失败了。
I have this on my page in _layout.cshtml so I always have a token available:
我在 _layout.cshtml 的页面上有这个,所以我总是有一个可用的令牌:
<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form>
I also have this method in my JavaScript utils file:
我的 JavaScript utils 文件中也有这个方法:
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};
This is all working as expected and I get an anti forgery token. My actual posting code is:
这一切都按预期工作,我得到了一个防伪令牌。我的实际发布代码是:
myPage.saveData = function() {
var saveUrl = '/exercises/PostData';
var myData = JSON.stringify(myPage.contextsArrays);
$.ajax({
type: 'POST',
async: false,
url: saveUrl,
data: AddAntiForgeryToken({ myResults: myData }),
success: function () {
alert('saved');
},
dataType: 'json',
contentType: "application/json; charset=utf-8"
});
};
My action method looks like this:
我的操作方法如下所示:
[HttpPost, ValidateAntiForgeryToken, JsonExceptionFilter]
public JsonResult PostData(List<ResultsDc> myResults)
{
return Json(_apiClient.SubmitResults(myResults));
}
I've been testing this with the various implementations I've been trying and the response is always:
我一直在用我一直在尝试的各种实现来测试这个,响应总是:
{"errorMessage":"The required anti-forgery form field \"__RequestVerificationToken\" is not present."}
I'm not posting a form it's just an array of data but checking the data that actually gets posted the Json doesn't look right (it's all encoded) but the __RequestVerificationToken parameter name is there and the token value is also present.
我不是发布表单,它只是一个数据数组,而是检查实际发布的数据,Json 看起来不正确(全部已编码),但 __RequestVerificationToken 参数名称在那里,并且令牌值也存在。
I'm pretty confused by all this at the moment and cannot find the correct way to send the token so that my MVC action is invoked. If I remove the ValidateAntiForgeryToken
attribute and have JSON.stringify(myPage.contextsArrays);
as the data the json looks correct (unencoded) and it maps fine.
目前我对这一切感到非常困惑,无法找到发送令牌的正确方法,以便调用我的 MVC 操作。如果我删除该ValidateAntiForgeryToken
属性并将其JSON.stringify(myPage.contextsArrays);
作为数据,则 json 看起来正确(未编码)并且映射良好。
How do I get this token posted properly without a form?
如何在没有表格的情况下正确发布此令牌?
回答by Jammer
Cardboard developer strikes again.
纸板开发商再次罢工。
All I had to do was remove:
我所要做的就是删除:
contentType: "application/json; charset=utf-8"
And by doing that (which changes the kind of post request being made), to get the Json content of the actual data property to bind correctly to your T
model type DO NOTJSON.stringify()
the data.
并且通过这样做(这会改变正在发出的发布请求的类型),以获取实际数据属性的 Json 内容以正确绑定到您的T
模型类型不要JSON.stringify()
数据。
回答by ESDictor
(NOTE: I know this isn't all that much different than what is already here)
(注意:我知道这与这里已有的并没有太大不同)
I realize this has already been answered, but I've done this quite a bit and will add my answer to the pile. I have no Forms in my site, so I had to come up with ways to handle this. A lot of research here on stackoverflow and some blogs finally gave me the info I needed.
我意识到这已经得到了回答,但我已经做了很多,并将我的答案添加到堆中。我的网站上没有表单,所以我必须想出办法来处理这个问题。在这里对 stackoverflow 和一些博客进行了大量研究,最终为我提供了所需的信息。
First, here's my code at the top of my "master" page (MVC Razor):
首先,这是我的“母版”页面(MVC Razor)顶部的代码:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
@Html.AntiForgeryToken()
}
Then, in all ajax calls (jQuery), I start like this:
然后,在所有 ajax 调用(jQuery)中,我都是这样开始的:
var token = $("#__AjaxAntiForgeryForm input").val();
var dataObject = {
__RequestVerificationToken: token,
myData: "whatever"
};
$.ajax({
url: '@Url.Action("action", "controller")',
type: 'POST',
dataType: 'json',
data: dataObject,
error: function (jqXHR, textStatus, errorThrown) {
console.log("ERROR!");
},
success: function (data) {
//whatever
}
});
Finally, in the Controller side of things, this works fine:
最后,在控制器方面,这很好用:
public class controllerController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult action (myModel myData)
{
return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet);
}
}
Hopefully this would help others in the same boat.
希望这会帮助其他人在同一条船上。
回答by user247702
The validation is hardcoded to look at form data.
验证是硬编码的以查看表单数据。
public AntiForgeryToken GetFormToken(HttpContextBase httpContext)
{
string value = httpContext.Request.Form[_config.FormFieldName];
You can simulate a form submission by following a certain format. For that, see How to mimic an HTML form submission in a POST request?
您可以通过遵循某种格式来模拟表单提交。为此,请参阅如何在 POST 请求中模拟 HTML 表单提交?
If you want, you can also make your own validator. How to POST JSON data to an Asp.Net MVC 2 app with ValidateAntiForgeryTokenexplains how to do this. It is for MVC 2 but you can pick up some ideas from it.
如果需要,您还可以制作自己的验证器。How to POST JSON data to an Asp.Net MVC 2 app with ValidateAntiForgeryToken解释了如何做到这一点。它适用于 MVC 2,但您可以从中获得一些想法。