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:
- Register the Antiforgery-Service
- Add the token to your request
- 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:
Add explicitly using
@Html.AntiForgeryToken()
,it will add an input type hidden with name__RequestVerificationToken
.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) { })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
Calling Unix and Linux Shared Object File .So from C#
Nullable Type as a Generic Parameter Possible
Why There Are 5 Versions of Timer Classes in .Net
Deserializing Dates with Dd/Mm/Yyyy Format Using JSON.Net
How to Check If Wpf Is Currently Executing in Design Mode or Not
What Does the Tilde Before a Function Name Mean in C#
Routing in ASP.NET MVC, Showing Username in Url
Css, Images, Js Not Loading in Iis
How to Transform String to Utf-8 in C#
Filesystemwatcher with Samba on Linux
Handle Modelstate Validation in ASP.NET Web API
How to Directly Execute SQL Query in C#
Read from Location on Console C#
Ignore Mapping One Property with Automapper
How to Force All Referenced Assemblies to Be Loaded into the App Domain