I have several Ajax.BeginForm on my MVC website. Meanwhile I need to handle the beforeSend event of my Ajax calls.
So the below code works for my manual jquery ajax calls, but it doesn't work with the Ajax.BeginForm helpers:
$.ajaxSetup({
'beforeSend': function (xhr) {
alert('');
}
});
Is there anyway to handle the beforeSend event on the MVC Ajax.BeginForm?
-------------------------------------------EDIT -------------------------------------
I need the before send event since I want to change the request headers :
'beforeSend': function (xhr) {
securityToken = $('[name=__RequestVerificationToken]').val();
xhr.setRequestHeader('__RequestVerificationToken', securityToken);
}
Thanks
I have several Ajax.BeginForm on my MVC website. Meanwhile I need to handle the beforeSend event of my Ajax calls.
So the below code works for my manual jquery ajax calls, but it doesn't work with the Ajax.BeginForm helpers:
$.ajaxSetup({
'beforeSend': function (xhr) {
alert('');
}
});
Is there anyway to handle the beforeSend event on the MVC Ajax.BeginForm?
-------------------------------------------EDIT -------------------------------------
I need the before send event since I want to change the request headers :
'beforeSend': function (xhr) {
securityToken = $('[name=__RequestVerificationToken]').val();
xhr.setRequestHeader('__RequestVerificationToken', securityToken);
}
Thanks
Share Improve this question edited Feb 20, 2014 at 18:45 Hugo Hilário asked Feb 20, 2014 at 18:33 Hugo HilárioHugo Hilário 2,9282 gold badges29 silver badges44 bronze badges 1- Possible duplicate - stackoverflow./questions/7877304/… – ramiramilu Commented Feb 20, 2014 at 18:42
2 Answers
Reset to default 4I think you are following samples from http://richiban.wordpress./2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/ This post does not address the support of Ajax form integration. I did some tests and found the solution.
I assume you use MVC4 with jquery-1.9.1.js
, jquery.validate.unobtrusive.js
and jquery.unobtrusive-ajax.js
referenced.
Following is my code
@model WebApplication1.Models.DummyModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.9.1.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
</head>
<body>
<div id="Parent">
@using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "post", OnBegin = "BeginClient" }))
{
@Html.AntiForgeryToken();
<div>First Name</div><div>@Html.TextAreaFor(m => m.FirstName)</div>
<div>Last Name</div><div>@Html.TextAreaFor(m => m.LastName)</div>
<input type="submit" value="Submit" />
}
</div>
<script type="text/javascript">
function BeginClient(xhr) {
alert("posting...");
securityToken = $('[name=__RequestVerificationToken]').val();
xhr.setRequestHeader('__RequestVerificationToken', securityToken);
}
$.ajaxSetup({
'beforeSend': function (xhr) {
securityToken = $('[name=__RequestVerificationToken]').val();
alert(securityToken);
xhr.setRequestHeader("__RequestVerificationToken", securityToken);
}
});
</script>
</body>
</html>
Basically you need to leverage onBegin
event, see http://johnculviner./ajax-beginform-ajaxoptions-custom-arguments-for-onplete-onsuccess-onfailure-and-onbegin/ there is clear explanation what is the parameters for each event.
Then in your global attribute class, your code looks like
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ValidateAntiForgeryTokenOnAllPostsAttribute : AuthorizeAttribute
{
/// <summary>
/// Executes authorization based on anti-forge token.
/// </summary>
/// <param name="filterContext">MVC pipeline filter context.</param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
// Only validate POSTs
if (request.HttpMethod == WebRequestMethods.Http.Post)
{
// Ajax POSTs and normal form posts have to be treated differently when it es to validating the AntiForgeryToken
if (request.IsAjaxRequest())
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute().OnAuthorization(filterContext);
}
}
}
}
By doing this way you can still force to use anti-forgery token with Ajax form.
Hope this helps.
For Ajax.BeginForm
you can use AjaxOptions.OnBegin:
@using (Ajax.BeginForm("actionName", "controllerName", new AjaxOptions() {
OnBegin = "requestBeginHandler"})) {
...markup here...
}
Update. To add new request header you can do something like this:
function requestBeginHandler(ajaxContext) {
var request = ajaxCOntext.get_request();
securityToken = $('[name=__RequestVerificationToken]').val();
request.get_headers()['__RequestVerificationToken'] = securityToken;
}