include antiforgerytoken in ajax post ASP.NET MVC
You have incorrectly specified the contentType
to application/json
.
Here's an example of how this might work.
Controller:
public class HomeController : Controller{ public ActionResult Index() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Index(string someValue) { return Json(new { someValue = someValue }); }}
View:
@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>
Another (less javascriptish) approach, that I did, goes something like this:
First, an Html helper
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));}
that will return a string
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
so we can use it like this
$(function () { $("#submit-list").click(function () { $.ajax({ url: '@Url.Action("SortDataSourceLibraries")', data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() }, type: 'post', traditional: true }); });});
And it seems to work!
it is so simple! when you use @Html.AntiForgeryToken()
in your html code it means that server has signed this page and each request that is sent to server from this particular page has a sign that is prevented to send a fake request by hackers. so for this page to be authenticated by the server you should go through two steps:
1.send a parameter named __RequestVerificationToken
and to gets its value use codes below:
<script type="text/javascript"> function gettoken() { var token = '@Html.AntiForgeryToken()'; token = $(token).val(); return token; }</script>
for example take an ajax call
$.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,});
and step 2 just decorate your action method by [ValidateAntiForgeryToken]