Ajax post with C# Handler and XSRF-TOKEN

Joseph Kashishian 85 Reputation points
2025-11-21T15:34:44.2166667+00:00

This question is for Web pages with .NET, C#, and Ajax.

I'm having an issue with a ajax calling working with the XSRF-TOKEN" and it's not calling the handler in the .CS. I think I need to do something with my ajax call to validate the token.

In my startup I have

        var antiforgery = app.ApplicationServices.GetRequiredService<IAntiforgery>();

        app.Use((context, next) =>

        {

            var requestPath = context.Request.Path.Value;

            if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)

                || string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))

            {

                var tokenSet = antiforgery.GetAndStoreTokens(context);

                context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,

                    new CookieOptions { HttpOnly = false });

            }

            return next(context);

        });

index cs

using System.IO;

using System.Data.SqlClient;

using System.Collections.Generic;

using Microsoft.AspNetCore.Http;

using Microsoft.Extensions.Configuration;

using Microsoft.AspNetCore.Mvc.RazorPages;

using Microsoft.AspNetCore.Mvc;

using System;

namespace RecoveryHouse.Pages.ReferralRequest

{

public class IndexModel : PageModel

{

    public void OnGet()

    {

    }

    [HttpPost]

    [ValidateAntiForgeryToken]

    public IActionResult OnPostGetTime(string name)

    {

        PersonModel person = new PersonModel

        {

            Name = name,

            DateTime = DateTime.Now.ToString()

        };

        return new JsonResult(person);

    }

}

}

public class PersonModel

{

/// <summary>

/// Gets or sets Name.

/// </summary>

public string Name { get; set; }

/// <summary>

/// Gets or sets DateTime.

/// </summary>

public string DateTime { get; set; }

}

Index CSHTML

@page

@model RecoveryHouse.Pages.ReferralRequest.IndexModel

@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width" />

<title>Index</title>

</head>

<body>

@Html.AntiForgeryToken()

<input type="text" id="txtName" />

<input type="button" id="btnGet" value="Get Current Time" />

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> 

<script type="text/javascript">

    $(function () {

        $("#btnGet").click(function () {

            $.ajax({

                type: "POST",

                url: "/Index?handler=GetTime",

                beforeSend: function (xhr) {

                    xhr.setRequestHeader("XSRF-TOKEN",

                        $('input:hidden[name="__RequestVerificationToken"]').val());

                },

                data: {"name": $("#txtName").val() },

                success: function (response) {

                    alert("Hello: " + response.Name + ".\nCurrent Date and Time: " + response.DateTime);

                },

                error: function (response) {

                    alert(response.responseText);

                }

            });

        });

    });

</script>

</body>

</html>

Developer technologies | ASP.NET Core | Other

Answer accepted by question author
SurferOnWww 6,106 Reputation points
2025-11-22T01:13:43.0666667+00:00

Please try the followings:

(1) Add form tag to .cshtml.

(2) Create the FormData object form the form tag.

(3) Send the FormData using jQuery ajax or fetch API.

Shown below are the samples:

Model

namespace RazorPages.Models
{
    public class PersonModel
    {
        public string Name { get; set; } = string.Empty;
        public string DateTime { get; set; } = string.Empty;
    }
}

.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPages.Models;

namespace RazorPages.Pages
{
    public class AjaxPostModel : PageModel
    {
        public void OnGet()
        {
        }

        [BindProperty]
        public PersonModel Model { get; set; } = default!;

        public IActionResult OnPost()
        {
            if (Request.Headers.XRequestedWith == "XMLHttpRequest")
            {
                string name = Model.Name;
                string dateTime = Model.DateTime;
                return Content($"Name: {name}, DateTime: {dateTime}");
            }
            else
            {
                return BadRequest();
            }
        }
    }
}

.cshtml

@page

@model RazorPages.Pages.AjaxPostModel
@{
    ViewData["Title"] = "AjaxPost";
}

<h1>AjaxPost</h1>

<hr />

<form method="post">
    <input type="text" name="name" />
    <br />
    <input type="text" name="datetime" />
    <br />
</form>

<input type="button" id="ajaxPost" value="POST" />

<div id="result"></div>

@section Scripts {
    <script type="text/javascript">
        //<![CDATA[
        document.getElementById("ajaxPost")
            .addEventListener('click', async () => {
                const fd = new FormData(document.querySelector("form"));
                const result = document.getElementById("result");                

                const param = {
                    method: "POST",
                    body: fd,
                    // set X-Requested-With in request header
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                }

                const response = await fetch("/ajaxpost", param);

                if (response.ok) {
                    const data = await response.text();
                    result.innerText = data;
                } else {
                    result.innerText = "response.ok is false";
                }
            });
        //]]>
    </script>
}

CSRF token in cookie sent to the server:

enter image description here

CSRF token in hidden field sent to the server:

enter image description here

Result

enter image description here

To see if the validation of CSRF-token is working, delete cookie of browser after the browser has received the response of OnGet() method and send the FormData by clicking the [POST] button. The ASP.NET will return 400 Bad request without invoking the OnPost() method.

Was this answer helpful?

0 comments No comments

6 additional answers

Sort by: Oldest
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.

    5 deleted comments

    Comments have been turned off. Learn more

  2. Joseph Kashishian 85 Reputation points
    2025-11-25T14:41:46.5366667+00:00

    Use answers to provide solutions to the user's question.this does not work in .net 7

    services.AddMvc()

           .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    
           .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
    

    services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

    Was this answer helpful?


  3. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.

    1 deleted comment

    Comments have been turned off. Learn more

  4. Joseph Kashishian 85 Reputation points
    2025-12-08T13:18:39.0666667+00:00

    I'm going to look at this this week. The issue has to do with the Version the application is on. It was a Asp.Core 2.1 migrated to .net 7 and there think there are some things in the configuration files stepping on the token toes. I was able to create a new solution and get it working but have not got it to work in my current project. I'm going to go thru some testing and process of elimination in the startup later in the week to see If I can narrow it down to the code causing the issue.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.