Nikolaj Herting Olsen
Nikolaj Herting Olsen

Reputation: 135

.NET CORE Razor Pages Ajax call to C# method

I am currently making a site to display locations on a google map. I get the location addresses from an Airtable.com database and everything there is working fine. However because google only allow a certain number of request to geocode addresses, i want to save the coordinates in the same database, so i only use the geocode api when a new location(address) needs to be looked up. I got that all setup, but i can't seem to figure out how i call a cs method from js in razor pages. I have used WebMethod in the past but i can't use that here apparently.

When i try to use the examples i find online, it says i need the RequestVerificationToken, but that needs the call to come from within a form(am i right?), and my ajax call is prompted when the site loads and it gets a location from the database which does not have any coordinates yet.

This is my first time using Razor Pages, so bear with me if i have totally misunderstood something.

Picture of my cs method i would like to call (Index.cshtml.cs) I tried with the httpPost tag, but it didn't make a difference

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

Picture of Ajax call from JavaScript, which is called on page load basically: AjaxCall

function updateRow(recordID, latLng) {
   console.log("REC_ID: " + recordID);
   console.log("LatLng: " + latLng);
   $.ajax({
       type: "POST",
       url: '/Index?OnPostGeoLocation', 
       contentType: "application/json; charset=utf-8",
       dataType: "json"
   }).done(function (data) {
       console.log(data.result);
   })
 }

Im aware that some of the code is not exactly what i need, but i just copied from online and will edit when im ahead of this hurdle .

Upvotes: 6

Views: 26810

Answers (2)

Nkosi
Nkosi

Reputation: 247521

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

Upvotes: 10

Nikolaj Herting Olsen
Nikolaj Herting Olsen

Reputation: 135

After reading Handle Ajax Requests in ASP.NET Core Razor Pages more carefully i figured out that i had indeed misunderstood some of the principles and that you CAN add AntiForgeryToken explicitly without a "form" tag, using @Html.AntiForgeryToken()

My code look like this now: enter image description here

And:

enter image description here

Upvotes: 3

Related Questions