最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ajax.BeginForm with BeforeSend - Stack Overflow

programmeradmin2浏览0评论

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
Add a ment  | 

2 Answers 2

Reset to default 4

I 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;
}
发布评论

评论列表(0)

  1. 暂无评论