Example Ajax Call Back to an ASP.NET Core Razor Page

Example AJAX call back to an ASP.NET Core Razor Page

Razor Pages automatically generates and validates Antiforgery tokens to prevent CSRF attacks. Since you aren't sending any token within your AJAX callback, the request fails.

To solve this problem you will have to:

  1. Register the Antiforgery-Service
  2. Add the token to your request
  3. Add the antiforgery token to your page either by adding a <form> or by directly using the @Html.AntiForgeryToken HtmlHelper

1. Register the Antiforgery-Service in your Startup.cs

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

2. Modify your AJAX callback

In the AJAX callback we add additional code to send the XSRF-TOKEN with our request header.

$.ajax({
type: "POST",
url: '/?handler=YOUR_CUSTOM_HANDLER', // Replace YOUR_CUSTOM_HANDLER with your handler.
contentType: "application/json; charset=utf-8",

beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},

dataType: "json"
}).done(function (data) {
console.log(data.result);
})

3. Add the antiforgery token to your page

You can accomplish this by adding a <form>:

<form method="post">
<input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />
</form>

or by using the @Html.AntiForgeryToken:

@Html.AntiForgeryToken()
<input type="button" value="Ajax test" class="btn btn-default" onclick="ajaxTest();" />

In both cases Razor Pages will automatically add a hidden input field which contains the antiforgery token once the page is loaded:

<input name="__RequestVerificationToken" type="hidden" value="THE_TOKEN_VALUE" />

.NET Core making an AJAX call from a Razor Page to a Controller

In Startup.cs, add this to ConfigureServices()

services.AddMvc(options => options.EnableEndpointRouting = false);

In Startupcs, also add this to Configure()

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

DisplayController.cs

public IActionResult Test()
{
return new JsonResult("Hi World");
}

Index.cshtml

<a onclick="ClickMe();">Click Me</a>
<script>
function ClickMe() {
$.get("/Display/Test", null, function (e) {
alert(e);
});
}
</script>

.NET CORE Razor Pages Ajax call to C# method

Try returning a proper IActionResult result.

[HttpPost]
public IActionResult OnPostGeoLocation() {
// Just to test that it actually gets called
Console.WriteLine("OnPostGeoLocation CALLED ####################################");

return new JsonResult("OnPostGeoLocation CALLED ####################################");
}

Next when making the call you need to call the correct handler path and include the anti-forgery token becasue, Razor Pages are designed to be automatically protected from cross-site request forgery (CSRF/XSRF) attacks.

Updated Ajax call

function updateRow(recordID, latLng) {
console.log("REC_ID: " + recordID);
console.log("LatLng: " + latLng);
$.ajax({
type: "POST",
url: '/Index?handler=GeoLocation',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function (data) {
console.log(data.result);
})
}

Very helpful article for reference

Handle Ajax Requests in ASP.NET Core Razor Pages

How to handle Ajax request with Razor Pages in ASP.NET Core, 2.0

I don't think you're able to access razor page action method like that. Can you try like this?

$.getJSON("/Customer?handler=ListofCustomer",function(data){
//Do something with the data.
});

Because to access any methods other than default OnGet or OnPost methods we require handlers, which run-time maps internally to the methods.

What is the url to ajax-call a C# function in an asp.net core razor pages application

Razor Pages is using page handlers for this. So if you want to POST to your page, create a method with the name OnPost{HandlerName} or OnPost{HandlerName}Async, if its an async method.

As an exmaple, if you have a form and want to delete something, You'd need a page handler like this:

public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var itemToDelete = await _mapRepo.GetByIdAsync(id);
if (itemToDelete == null)
{
//...
}

await _mapRepo.Delete(itemToDelete);
return RedirectToPage("Maps");
}

The OnPost declares, that asp.net core will listen for a POST request, Delete is the name, while Async is a naming convention for async handlers.

In your form, you would then simply declare an input element, that would call this handler during the onclick event:

<button type="submit" class="btn btn-danger btn-block" asp-page-handler="Delete" asp-route-id="@Model.Id">Delete</button>

Doing this with ajax:

$.ajax
({
type: "POST",
url: "/builder?handler=HelloFunc",
dataType: "text",
success: function (result) {
alert(result);
},
error: function (status, ex) {
alert("Error Code: Status: " + status + " Ex: " + ex);
}
});

With a handler method:

public void OnPostHelloFunc()
{
//...
}

Here is a good read on named handlers: https://www.learnrazorpages.com/razor-pages/handler-methods

Asp .Net Core 2.2 Razor Pages Ajax Call Post not working

As you've already found out it's the anti forgery token, that is ruining your day.
Now, if you are inside a form, asp.net core will create a hidden input with that token for you. If you are not working with a form on your page, you'll have to call @Html.AntiForgeryToken(), which will add the token for you.
Still, this will not resolve the Bad Request for you. You have to add it to your ajax call:

$.ajax({
url: "/Account/Users/Index?handler=Delete",
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
id: id
},
});

Additionally, add this line to your Startup.cs file:

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

Change target of ajax post in razor page from api in controller to code-behind post handler in same razor page

Razor Pages are designed to be automatically protected from cross-site request forgery (CSRF/XSRF) attacks.

You should send the anti-forgery token in request header to the server using AJAX:

  1. Add explicitly using @Html.AntiForgeryToken() ,it will add an input type hidden with name __RequestVerificationToken.

  2. Send token in request header :

    $.ajax({
    url: '/Index',
    type: 'POST',
    beforeSend: function (xhr) {
    xhr.setRequestHeader("XSRF-TOKEN",
    $('input:hidden[name="__RequestVerificationToken"]').val());
    },
    })
    .done(function (result) { })
  3. Configure the antiforgery service to look for the X-CSRF-TOKEN header :

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

Below article is for your reference :

Handle Ajax Requests in ASP.NET Core Razor Pages



Related Topics



Leave a reply



Submit