jquery ajax post goes to the wrong action method in MVC 4 - asp.net

Here is my view
<div>
#using ( Html.BeginForm("jQueryPost", "Home",null, FormMethod.Post, new { id="FormPost" }))
{
#Html.TextBoxFor(x=> x.Name)<br />
#Html.TextBoxFor(x => x.LastName)<br />
#Html.TextBoxFor(x => x.Age)
<input type=submit value="submit" />
}
</div>
<script>
$(document).ready(function () {
$('#FormPost').submit(function (e) {
//This line will prevent the form from submitting
e.preventDefault();
alert('ajax post here');
$.ajax({
type: 'POST',
url: $('FormPost').attr('action'),
data: $('FormPost').serialize(),
accept: 'application/json',
error: function (xhr, status, error) {
alert('error: ' + xhr.statusText);
},
success: function (response) {
alert('resp: ' + response.data);
}
});
});
});
</script>
These are the Home controller's methods:
public ActionResult Index()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult jQueryPost(IndexVM vm)
{
IndexVM _vm = vm;
return Json("name posted was: " + _vm.Name);
}
This is the route map
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When the page loads it goes to the Index action method, which is understandable. However, when I submit the form it is going to the Index action method again. Why is that?
The alert message 'ajax post here' gets shown followed by the success alert ('resp: ' + response.data). However since I am not returning anything in the Index I get a resp: undefined in the alert box.
How do I fix this so that the form post goes to the public JsonResult jQueryPost(IndexVM vm) method? I also tried replacing the JsonResult to ActionResult and it fared the same.

You forgot the # in you jQuery selectors:
$.ajax({
type: 'POST',
url: $('#FormPost').attr('action'),
data: $('#FormPost').serialize(),
accept: 'application/json',
error: function (xhr, status, error) {
alert('error: ' + xhr.statusText);
},
success: function (response) {
alert('resp: ' + response.data);
}
});

Related

DotNetNuke mvc fill in form items on SelectList change

I am trying to populate form items based on a dropdown selection without refreshing the entire page or loading a new view. This was fairly simple in web forms using an UpdatePanel, for instance. However, I can't get this to work in MVC.
I've tried many of the solutions I could find. I don't know if this is a DotNetNuke issue.
Debugging shows the controller firing and retrieving a record but the form items are never populated.
I've tried both a jquery.post and an .ajax call. Neither work.
View:
#inherits DotNetNuke.Web.Mvc.Framework.DnnWebViewPage<IMS.Model.lh.Associations>
#using IMT.LH.AssociationAdmin.Models
#using IMS.Model.lh
#{
ViewBag.Title = "Association";
}
<h2>Association</h2>
<div id="Associations-#Dnn.ModuleContext.ModuleId">
#Html.DropDownList("SelectAssociation")
</div>
<div id="Association-#Dnn.ModuleContext.ModuleId">'
#Html.LabelFor(m=>m.AssociationID)<br />
#Html.Label("Title")<br />
#Html.Label("Slug")<br />
#Html.Label("Description")<br />
#Html.Label("Tagline")<br/>
</div>
<script type="text/javascript">
const rvtoken = $("input[name='__RequestVerificationToken']").val();
const moduleId = #Dnn.ModuleContext.ModuleId;
const tabId = #Dnn.ModuleContext.TabId;
$.ajaxSetup({
headers: {
"RequestVerificationToken": rvtoken
}
});
$('#SelectAssociation').change(
function() {
$.post(
"/DesktopModules/MVC/LH.AssociationAdmin/Association/SelectAssociation",
{
id: $(this).val()
}),
function() {
alert("success");
}
/*$.ajax({
url: "/DesktopModules/MVC/LH.AssociationAdmin/Association/SelectAssociation",
method: "Post",
data: {
id: $(this).val()
},
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken
},
success: function() {
alert("success");
},
fail: function() {
alert("fail");
}
});
*/
});
</script>
Controller:
[HttpPost]
[DotNetNuke.Web.Mvc.Framework.ActionFilters.ValidateAntiForgeryToken]
public ActionResult SelectAssociation()
{
ModelState.Clear();
int id = Convert.ToInt32(Request.Form["id"]);
using (var ac = new AssociationsController())
{
ac.GetById(id);
return PartialView("Index", ac.CurrentRec);
}
}
Ok. One way I've found is to simply return a json object to the .ajax call and parse it:
$.ajax({
cache: false,
dataType: 'json',
url: "/DesktopModules/MVC/LH.AssociationAdmin/Association/SelectAssociation",
method: "Post",
data: {
id: $(this).val()
},
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken
},
success: function(data) {
//alert(data.AssociationID);
$('#AssociationID').text(data.AssociationID);
$('#Title').text(data.Title);
$('#Slug').text(data.Slug);
$('#Description').text(data.Description);
$('#Tagline').text(data.Tagline);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
console.log(jqXHR);
}
});
});
Controller:
[HttpPost]
[DotNetNuke.Web.Mvc.Framework.ActionFilters.ValidateAntiForgeryToken]
public ActionResult SelectAssociation()
{
ModelState.Clear();
int id = Convert.ToInt32(Request.Form["id"]);
using (var ac = new AssociationsController())
{
ac.GetById(id);
return Json(ac.CurrentRec);
//return PartialView("Index", ac.CurrentRec);
}
}
But, I am certainly open to other suggestions.

After getting the search value by Ajax, redirect to result another View

The parameter, search, comes from Index view by Ajax post. After the search process I want to send the employees object to Result view. Result action and view are in the same controller and same view folder. But RedirectToAction(employees) doesn't affect. There is no problem about getting search value from view by Ajax or about getting corresponding employees from database, all of them are fine. This post says you cannot redirect from Ajax post. I don't know how can I redirect & send the employees object to Result view. I don't want to make this via ViewBag.
[HttpPost]
public async Task<IActionResult> Result([FromBody]string search)
{
if (string.IsNullOrEmpty(search))
{
return NotFound();
}
IEnumerable<Employee> employees = await _context.Employees.Where(e => e.Surname == search).ToListAsync();
return RedirectToAction("Index", employees);
}
$(document).ready(function () {
$('.SearchButton').on('click', function (e) {
e.preventDefault();
var searchVal = $('.Search').val();
console.log(searchVal);
$.ajax(
{
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("Index", "Employee")',
data: JSON.stringify(searchVal),
dataType: 'json',
success: function (response) {
console.log(response);
},
error: function (response) {
console.log(response.message);
}
});
});
});
I created a Result view instead of trying to redirect to Index view, removed the HttpPost and FromBody attribute from Result action, changed the "return RedirectToAction("Index", employees)" to "return View(employee)"
public async Task<IActionResult> Result(string search)
{
if (string.IsNullOrEmpty(search))
{
return NotFound();
}
IEnumerable<Employee> employees = await _context.Employees.Where(e => e.Surname == search).ToListAsync();
return View(employees);
}
<input type="text" class="Search" placeholder="Search by surname" /><a class="SearchButton">Search</a>
Then delete the whole jQuery code and replace with this lines of code:
$(document).ready(function () {
$('.SearchButton').on('click', function (e) {
window.location.href = '#Url.Action("Result")' + '/?search=' + $('.Search').val();
});
});

Sending parameters of selected values to controller

I have html like this:
HTML
<div class="col-md-3 col-sm-12">
<div>
<p>Región</p>
<select id="lstRegion" class="form-control agenda_space" aria-hidden="true"></select>
</div>
<div>
<p>Solicitud</p>
<select id="lstSolicitud" class="form-control agenda_space" aria-hidden="true"> </select>
</div>
<br/>
<div>
Actualizar Filtro
<br/>
</div>
JS:
$("#lstRegion")
.getJSONCatalog({
onSuccess: function (response) {
console.log(response);
},
url: '/Agenda/GetRegion',
valueProperty: "ID",
textProperty: "valor"
});
//Load solicitud dropdown
$("#lstSolicitud")
.getJSONCatalog({
url: '/Agenda/GetSolicitud',
valueProperty: "ID",
textProperty: "solicitud"
});
Controller:
public ActionResult GetRegion()
{
try
{
var listaRegistros = db.CatalogoRegistros.Where(x => x.CatalogosCodigo == "REGI").Select(x => new
{
x.ID
,
valor = x.Valor
});
return Json(listaRegistros, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
throw ex;
}
}
public ActionResult GetSolicitud()
{
try
{
var listasolicitud = db.Solicitudes.Select(x => new { x.ID, solicitud = "Folio: " + x.ID });
return Json(listasolicitud, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
throw ex;
}
}
They work great I get my dropdwon lists very well, but now I want to do a GET action with selected values of each dropdown when my Actualizar Filtro it´s clicked.
But I´m really new in asp.net and I don´t know what I need to do to get selected values and send to controller.
As googling it I found I need to do method into my controller to get values so:
Controller will be:
public ActionResult GetTareas(string lstRegionValue, string lstsolicitudValue)
{
}
But I don´t know how to send them via JS, how can I do that to receive selected parameters into my controller? Regards
UPDATE
I try it using Ajax like:
$.ajax({
type: 'GET',
url: '#Url.Action("Agenda", "GetTareas")',
data: { region: $('#lstRegion option:selected').html(), solicitud: $('#lstSolicitud option:selected').html() }, // pass the value to the id parameter
dataType: 'json',
success: function (data) {
console.log(data);
}});
But how can I trigger that function when event_add is clicked?
To run your updated ajax code on click, add #event_add click event handler and run your code inside it.
$('#event_add').click(function(e){
e.preventDefault(); //suppress default behavior
$.ajax({
type: 'GET',
url: '#Url.Action("Agenda", "GetTareas")', // don't hard code your urls
data: { region: $('#lstRegion option:selected').html(), solicitud:
$('#lstSolicitud option:selected').html() }, // pass the value to the id parameter
dataType: 'json', // your returning a view, not json
success: function (data) {
console.log(data);
}});
});
Hi Try the below updated code:
$('#event_add').click(function(e){
var regionval = $('#lstRegion option:selected').html(),
var solicval = $('#lstSolicitud option:selected').html(),
$.ajax({
type: 'GET',
url: '#Url.Action("Agenda", "GetTareas", new { lstRegionValue = regionval, lstsolicitudValue =solicval})',
});
});
Note : I didnt test the code, but hope that it should work for you
Controller code:
public ActionResult GetTareas(string lstRegionValue, string lstsolicitudValue)
{
}
Hope it helps , thanks

Alert box like stackoverflow dynamic data

Want to add an alert box like stackoverflow. i saw some good examples but not something i want. I want different messages that are appearing on different occasions.
ex. I want this msg from C# code when user logins.
Also when user places an order.
or something is wrong.
This answer is good but the message is appearing on page load. Another example demonstrate the same.
You need to create a generic-http-handler or web service or page-method and call it through jQuery and show the message on the alert.
create a handler like this
public class VideoViewValidation : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string videoID = string.Empty;
string id = context.Request["Id"];
context.Response.Writ("your message");
}
}
and call it through jQuery on button client click
$.ajax({
url: 'VideoViewValidation.ashx',
type: 'POST',
data: { 'Id': '10000', 'Type': 'Employee' },
contentType: 'application/json;charset=utf-8',
success: function (data) {
alert('Server Method is called successfully.' + data.d);
},
error: function (errorText) {
alert('Server Method is not called due to ' + errorText);
}
});
If you don't want to do it on page load but you want it to be driven by code behind (C#) you'll need to use AJAX.
Using JQuery this is easily accomplished by doing something like the following (this is my generic 'perform this action on this controller' in ASP.NET MVC):
<script type="text/javascript">
function execute(controller, action) {
$.ajax({
type: 'get',
url: ('/' + controller + '/' + action),
dataType: 'text'
}).done(function (data, textStatus, jqXHR) {
$('#response').html(data).slideDown();
}).fail(function (jqXHR, textStatus, errorThrown) {
$('#response').html(jqXHR.responseText).slideDown();
});
}
</script>
You can expand this out to pass whatever data you need to whatever URL you need such as:
<script type="text/javascript">
function execute(controller, action, username, password) {
$.ajax({
type: 'get',
url: ('/' + controller + '/' + action),
dataType: 'text',
data: ('username='+username+'&password='+password)
}).done(function (data, textStatus, jqXHR) {
$('#response').html(data).slideDown();
}).fail(function (jqXHR, textStatus, errorThrown) {
$('#response').html(jqXHR.responseText).slideDown();
});
}
</script>
On the server side you just return the string of what you want the response to say, such as "Success! You've been logged in!" and then the element id'ed "response" will have its inner HTML swapped out with that response, and then will be slid open:
<div id="response" style="display:none"></div>
Be aware that the .fail() event will push out the entire error page you would throw if you don't just return a string on a thrown exception. .fail() will trigger if the HTTP status code from the server is not 200 (OK).
If you're using ASP.NET MVC your C# code can look like this:
namespace MySite.Controllers
{
public class SomeController : Controller
{
public string Login(string username, string password){
// Process login
return "You've been logged in!";
}
}
}
If you're using Webforms:
//On Page_Load() call a function if it's an AJAX Login
// such as
if(Request["ajax"] == "login"){
AjaxLogin(Request["username"], Request["password"]);
}
private void AjaxLogin(string username, string password){
// Process login
Response.Write("Ajax login complete!");
Response.End(); // Don't send anything else and stop processing request.
}
Then to call it simply pass the variables to your function:
<a onclick="execute('MyController', 'Login', 'UserName', 'MyPass')">Login!</a>
Obviously this assume you have the data you need to process a login request before they enter it, which would be a little self defeating so you can extend out a specific function using JQuery to grab form element content such as:
<input type="text" name="username" id="username" />
<input type="text" name="password" id="password" />
Then in your function add:
<script type="text/javascript">
function login(controller, action) {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
$.ajax({
type: 'get',
url: ('/' + controller + '/' + action),
dataType: 'text',
data: ('username='+username+'&password='+password)
}).done(function (data, textStatus, jqXHR) {
$('#response').html(data).slideDown();
}).fail(function (jqXHR, textStatus, errorThrown) {
$('#response').html(jqXHR.responseText).slideDown();
});
}
</script>
try this
public void message(string msg)
{
ScriptManager.RegisterClientScriptBlock(this, GetType(), "Done", "alert('" + msg + "');", true);
}
to use this method
write message("You are logged in sucessfully.");

include antiforgerytoken in ajax post ASP.NET MVC

I am having trouble with the AntiForgeryToken with ajax. I'm using ASP.NET MVC 3. I tried the solution in jQuery Ajax calls and the Html.AntiForgeryToken(). Using that solution, the token is now being passed:
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) {
...
}
});
When I remove the [ValidateAntiForgeryToken] attribute just to see if the data (with the token) is being passed as parameters to the controller, I can see that they are being passed. But for some reason, the A required anti-forgery token was not supplied or was invalid. message still pops up when I put the attribute back.
Any ideas?
EDIT
The antiforgerytoken is being generated inside a form, but I'm not using a submit action to submit it. Instead, I'm just getting the token's value using jquery and then trying to ajax post that.
Here is the form that contains the token, and is located at the top master page:
<form id="__AjaxAntiForgeryForm" action="#" method="post">
#Html.AntiForgeryToken()
</form>
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]
In Asp.Net Core you can request the token directly, as documented:
#inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
#functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
And use it in javascript:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": '#GetAntiXsrfRequestToken()' });
}
You can add the recommended global filter, as documented:
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
Update
The above solution works in scripts that are part of the .cshtml. If this is not the case then you can't use this directly. My solution was to use a hidden field to store the value first.
My workaround, still using GetAntiXsrfRequestToken:
When there is no form:
<input type="hidden" id="RequestVerificationToken" value="#GetAntiXsrfRequestToken()">
The name attribute can be omitted since I use the id attribute.
Each form includes this token. So instead of adding yet another copy of the same token in a hidden field, you can also search for an existing field by name. Please note: there can be multiple forms inside a document, so name is in that case not unique. Unlike an id attribute that should be unique.
In the script, find by id:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": $('#RequestVerificationToken').val() });
}
An alternative, without having to reference the token, is to submit the form with script.
Sample form:
<form id="my_form" action="/something/todo/create" method="post">
</form>
The token is automatically added to the form as a hidden field:
<form id="my_form" action="/something/todo/create" method="post">
<input name="__RequestVerificationToken" type="hidden" value="Cf..." /></form>
And submit in the script:
function DoSomething() {
$('#my_form').submit();
}
Or using a post method:
function DoSomething() {
var form = $('#my_form');
$.post("/something/todo/create", form.serialize());
}
In Asp.Net MVC when you use #Html.AntiForgeryToken() Razor creates a hidden input field with name __RequestVerificationToken to store tokens. If you want to write an AJAX implementation you have to fetch this token yourself and pass it as a parameter to the server so it can be validated.
Step 1: Get the token
var token = $('input[name="`__RequestVerificationToken`"]').val();
Step 2: Pass the token in the AJAX call
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')
}
})
};
Note: The content type should be 'application/x-www-form-urlencoded; charset=utf-8'
I have uploaded the project on Github; you can download and try it.
https://github.com/lambda2016/AjaxValidateAntiForgeryToken
function DeletePersonel(id) {
var data = new FormData();
data.append("__RequestVerificationToken", "#HtmlHelper.GetAntiForgeryToken()");
$.ajax({
type: 'POST',
url: '/Personel/Delete/' + id,
data: data,
cache: false,
processData: false,
contentType: false,
success: function (result) {
}
});
}
public static class HtmlHelper
{
public static string GetAntiForgeryToken()
{
System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), "(?:value=\")(.*)(?:\")");
if (value.Success)
{
return value.Groups[1].Value;
}
return "";
}
}
In Account controller:
// POST: /Account/SendVerificationCodeSMS
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult SendVerificationCodeSMS(string PhoneNumber)
{
return Json(PhoneNumber);
}
In View:
$.ajax(
{
url: "/Account/SendVerificationCodeSMS",
method: "POST",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
dataType: "json",
data: {
PhoneNumber: $('[name="PhoneNumber"]').val(),
__RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
},
success: function (data, textStatus, jqXHR) {
if (textStatus == "success") {
alert(data);
// Do something on page
}
else {
// Do something on page
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(jqXHR.status);
console.log(jqXHR.statusText);
console.log(jqXHR.responseText);
}
});
It is important to set contentType to 'application/x-www-form-urlencoded; charset=utf-8' or just omit contentTypefrom the object ...
I know this is an old question. But I will add my answer anyway, might help someone like me.
If you dont want to process the result from the controller's post action, like calling the LoggOff method of Accounts controller, you could do as the following version of #DarinDimitrov 's answer:
#using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
#Html.AntiForgeryToken()
}
<!-- this could be a button -->
Submit
<script type="text/javascript">
$('#ajaxSubmit').click(function () {
$('#__AjaxAntiForgeryForm').submit();
return false;
});
</script>
For me the solution was to send the token as a header instead of as a data in the ajax call:
$.ajax({
type: "POST",
url: destinationUrl,
data: someData,
headers:{
"RequestVerificationToken": token
},
dataType: "json",
success: function (response) {
successCallback(response);
},
error: function (xhr, status, error) {
// handle failure
}
});
The token won't work if it was supplied by a different controller. E.g. it won't work if the view was returned by the Accounts controller, but you POST to the Clients controller.
I tried a lot of workarrounds and non of them worked for me. The exception was "The required anti-forgery form field "__RequestVerificationToken" .
What helped me out was to switch form .ajax to .post:
$.post(
url,
$(formId).serialize(),
function (data) {
$(formId).html(data);
});
Feel free to use the function below:
function AjaxPostWithAntiForgeryToken(destinationUrl, successCallback) {
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: "POST",
url: destinationUrl,
data: { __RequestVerificationToken: token }, // Your other data will go here
dataType: "json",
success: function (response) {
successCallback(response);
},
error: function (xhr, status, error) {
// handle failure
}
});
}
Create a method that will responsible to add token
var addAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $("[name='__RequestVerificationToken']").val();
return data;
};
Now use this method while passing data/parameters to Action like below
var Query = $("#Query").val();
$.ajax({
url: '#Url.Action("GetData", "DataCheck")',
type: "POST",
data: addAntiForgeryToken({ Query: Query }),
dataType: 'JSON',
success: function (data) {
if (data.message == "Success") {
$('#itemtable').html(data.List);
return false;
}
},
error: function (xhr) {
$.notify({
message: 'Error',
status: 'danger',
pos: 'bottom-right'
});
}
});
Here my Action have a single parameter of string type
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult GetData( string Query)
{
#using (Ajax.BeginForm("SendInvitation", "Profile",
new AjaxOptions { HttpMethod = "POST", OnSuccess = "SendInvitationFn" },
new { #class = "form-horizontal", id = "invitation-form" }))
{
#Html.AntiForgeryToken()
<span class="red" id="invitation-result">#Html.ValidationSummary()</span>
<div class="modal-body">
<div class="row-fluid marg-b-15">
<label class="block">
</label>
<input type="text" id="EmailTo" name="EmailTo" placeholder="forExample#gmail.com" value="" />
</div>
</div>
<div class="modal-footer right">
<div class="row-fluid">
<button type="submit" class="btn btn-changepass-new">send</button>
</div>
</div>
}

Resources