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.
I have this on my page in _layout.cshtml so I always have a token available:
<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form>
I also have this method in my JavaScript utils file:
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.
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.
How do I get this token posted properly without a form?
The basic purpose of ValidateAntiForgeryToken attribute is to prevent cross-site request forgery attacks. A cross-site request forgery is an attack in which a harmful script element, malicious command, or code is sent from the browser of a trusted user.
The URL for the jQuery AJAX call is set to the Controller's action method i.e. /Home/AjaxMethod. The value of the AntiForgery Token and value of the TextBox is passed as parameter and the returned response is displayed using JavaScript Alert Message Box.
AntiForgeryToken()Generates a hidden form field (anti-forgery token) that is validated when the form is submitted.
Validates that input data from an HTML form field comes from the user who submitted the data. Validates that input data from an HTML form field comes from the user who submitted the data.
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 NOT JSON.stringify()
the data.
(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.
First, here's my code at the top of my "master" page (MVC Razor):
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) { @Html.AntiForgeryToken() }
Then, in all ajax calls (jQuery), I start like this:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With