在ASP.NET MVC中的ajax中包含antiforgerytoken
AntiForgeryToken和ajax有问题。 我正在使用ASP.NET MVC 3.我尝试了jQuery Ajax调用和Html.AntiForgeryToken()的解决scheme。 使用该解决scheme,令牌现在正在传递:
var data = { ... } // with token, key is '__RequestVerificationToken' $.ajax({ type: "POST", data: data, datatype: "json", traditional: true, contentType: "application/json; charset=utf-8", url: myURL, success: function (response) { ... }, error: function (response) { ... } });
当我删除[ValidateAntiForgeryToken]
属性来查看数据(带有令牌)是否作为parameter passing给控制器时,我可以看到它们正在被传递。 但由于某种原因, A required anti-forgery token was not supplied or was invalid.
当我把属性放回去时,消息仍然popup。
有任何想法吗?
编辑
表单中生成了防伪标记,但是我没有使用提交操作来提交它。 相反,我只是使用jquery获取令牌的值,然后尝试ajax后。
以下是包含令牌的表单,位于顶级主页面:
<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken() </form>
您错误地指定了contentType
到application/json
。
这是一个如何工作的例子。
控制器:
public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Index(string someValue) { return Json(new { someValue = someValue }); } }
视图:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) { @Html.AntiForgeryToken() } <div id="myDiv" data-url="@Url.Action("Index", "Home")"> Click me to send an AJAX request to a controller action decorated with the [ValidateAntiForgeryToken] attribute </div> <script type="text/javascript"> $('#myDiv').submit(function () { var form = $('#__AjaxAntiForgeryForm'); var token = $('input[name="__RequestVerificationToken"]', form).val(); $.ajax({ url: $(this).data('url'), type: 'POST', data: { __RequestVerificationToken: token, someValue: 'some value' }, success: function (result) { alert(result.someValue); } }); return false; }); </script>
另一个 (较lessjavascriptish)的方法,我做了这样的事情:
首先,一个Html帮手
public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper) { var antiForgeryInputTag = helper.AntiForgeryToken().ToString(); // Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" /> var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", ""); var tokenValue = removedStart.Replace(@""" />", ""); if (antiForgeryInputTag == removedStart || removedStart == tokenValue) throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect."); return new MvcHtmlString(string.Format(@"{0}:""{1}""", "__RequestVerificationToken", tokenValue)); }
这将返回一个string
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
所以我们可以像这样使用它
$(function () { $("#submit-list").click(function () { $.ajax({ url: '@Url.Action("SortDataSourceLibraries")', data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() }, type: 'post', traditional: true }); }); });
它似乎工作!
它是如此简单! 当你在你的html代码中使用@Html.AntiForgeryToken()
,这意味着服务器已经对这个页面进行了签名,并且从这个特定页面发送到服务器的每个请求都有一个阻止黑客发送虚假请求的标志。 所以为了让这个页面被服务器authentication,你应该经过两个步骤:
发送一个名为__RequestVerificationToken的参数,并获取如下的值使用代码:
<script type="text/javascript"> function gettoken() { var token = '@Html.AntiForgeryToken()'; token = $(token).val(); return token; } </script>
例如采取ajax电话
$.ajax({ type: "POST", url: "/Account/Login", data: { __RequestVerificationToken: gettoken(), uname: uname, pass: pass }, dataType: 'json', contentType: 'application/x-www-form-urlencoded; charset=utf-8', success: successFu, });
和第2步只是通过[ValidateAntiForgeryToken]
装饰你的行动方法
函数DeletePersonel(id){ var data = new FormData(); data.append(“__ RequestVerificationToken”,“@ HtmlHelper.GetAntiForgeryToken()”); $就({ 键入:'POST', url:'/ Personel / Delete /'+ id, 数据:数据, caching:假, processData:false, contentType:false, 成功:function(结果){ } }); } 公共静态类HtmlHelper { 公共静态stringGetAntiForgeryToken() { System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml()。ToString(),“(?:value = \”)(。*)(? :\ “)”); 如果(value.Success) { 返回值.Groups [1] .Value; } 返回“”; } }
我知道这是一个古老的问题。 但无论如何,我会加我的答案,可能会帮助像我这样的人。
如果你不想处理控制器后操作的结果,比如调用Accounts
控制器的LoggOff
方法,你可以像以下版本的@DarinDimitrov的回答一样:
@using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) { @Html.AntiForgeryToken() } <!-- this could be a button --> <a href="#" id="ajaxSubmit">Submit</a> <script type="text/javascript"> $('#ajaxSubmit').click(function () { $('#__AjaxAntiForgeryForm').submit(); return false; }); </script>
我尝试了很多workarrounds,而他们没有为我工作。 例外是“所需的防伪表单字段”__RequestVerificationToken“。
帮助我的是将表单.ajax转换为.post:
$.post( url, $(formId).serialize(), function (data) { $(formId).html(data); });
在Asp.Net MVC中,当你使用@Html.AntiForgeryToken()
Razor创build一个名为__RequestVerificationToken
的隐藏input字段来存储令牌。 如果你想编写一个AJAX实现,你必须自己获取这个token,并把它作为parameter passing给服务器,这样就可以validation了。
第1步:获取令牌
var token = $('input[name="`__RequestVerificationToken`"]').val();
第2步:在AJAX调用中传递令牌
function registerStudent() { var student = { "FirstName": $('#fName').val(), "LastName": $('#lName').val(), "Email": $('#email').val(), "Phone": $('#phone').val(), }; $.ajax({ url: '/Student/RegisterStudent', type: 'POST', data: { __RequestVerificationToken:token, student: student, }, dataType: 'JSON', contentType:'application/x-www-form-urlencoded; charset=utf-8', success: function (response) { if (response.result == "Success") { alert('Student Registered Succesfully!') } }, error: function (x,h,r) { alert('Something went wrong') } }) };
注意 :内容types应该是'application/x-www-form-urlencoded; charset=utf-8'
'application/x-www-form-urlencoded; charset=utf-8'
我已经在Github上传了这个项目。 你可以下载并尝试它。