Search code examples
c#jsonajaxasp.net-mvcantiforgerytoken

ValidateAntiforgeryToken not working with Ajax in ASP.NET MVC


Having this View:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
    <div id='calendar'></div>
    <script src="~/Scripts/Services/Agenda.js" type="text/javascript"></script>
}

The following two lines of JS code are executed:

let form = $('#__AjaxAntiForgeryForm');
let token = $('input[name="__RequestVerificationToken"]', form).val();

Then this function is called:

function dbUpdate(data, startTime, title) {
    let evento = JSON.stringify({
        'Data': data,
        'StartTime': startTime,
        'Title': title,
        '__RequestVerificationToken': token
    });

    $.ajax({
        type: "POST",
        url: 'Agenda/DbUpdate',
        data: evento,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            console.log("Response");
        },
        complete: function () {
            console.log("After");
        },
        failure: function (jqXHR, textStatus, errorThrown) {
            alert("HTTP Status: " + jqXHR.status + "; Error Text: " + jqXHR.responseText); // Display error message
        }
    });
}

- Example of the Json generated:

  {
  "Data":"2020-0105T03:00:00.000Z",
  "StartTime":"8",
   "Title":"Sdf",
   "__RequestVerificationToken":"IMBfPM4YPyslt_89W6Kfu_Nmy6OW2-8I4n3fp42Figy__2gid3wY8gMC- 
   glB2o3Y6v6TCEG18nZXRPfLltU2RpOvoy-rMFIyo-uPA2XL4JcFF1aJfXix6RWkTI5l6Ewqhyu5jSQnszEOre2ZP-az3Q2"
  }

The controller is:

[HttpPost]
[AjaxAuthorize]
[ValidateAntiForgeryToken]
public async Task<JsonResult> DbUpdate(AgendaEvent compromisso)
{
    ...
    return Json("ok");
}

And the AgendaEvent class:

public DateTime Data { get; set; }
public string StartTime { get; set; }
public string Title { get; set; }
public string __RequestVerificationToken { get; set; }

Just a note, if I make the class without the __RequestVerificationToken, thus being:

public DateTime Data { get; set; }
public string StartTime { get; set; }
public string Title { get; set; }

I receive an error 404.

But the token, even though is present in the data passed is not validated.

What's wrong?


Solution

  • As suggested by lordvlad30 the error was due the line:

    let evento = JSON.stringify({
        'Data': data,
        'StartTime': startTime,
        'Title': title,
        '__RequestVerificationToken': token
    });
    

    Specifically, it's not supposed to have the JSON.stringify() statement. Thus, the correct is:

    let evento = {
        'Data': data,
        'StartTime': startTime,
        'Title': title,
        '__RequestVerificationToken': token
    };
    

    And everything works!