Home > Net >  AJAX call returns 404 on server, works locally
AJAX call returns 404 on server, works locally

Time:02-18

In my application I have a drop-down menu that lists various customers, and a second drop-down that will list the cities with which a given customer is associated. Selecting a customer should populate the second drop-down with the relevant list of locations. This happens by triggering an Ajax call to a method in the controller, which passes the name of the selected customer in variable "loc". The list of locations is obtained via an EF Core query.

This all works as expected on my local machine, but when running on our server it returns a 404 - Not Found error.

The Ajax call looks like this:

$.ajax({
     url: "/[Controller]/GetLocations",
     type: "POST",
     dataType: "text",
     data: { 'loc': loc },
     success: function (data, textStatus, jqXHR) {

        var listData = JSON.parse(data);
        resetLocationList();
        for (var listSize = 0; listSize < listData.length; listSize  ) {
             $('#ffBankLocation').append('<option value="'   listData[listSize]   '">'   
             listData[listSize]   '</option>');
        }

     },
     error: function (jqXHR, textStatus, errorThrown) {
        console.log('Error caught: ');
        console.log(errorThrown);
     }
});

And the method in the controller looks like this:

[HttpPost]
public async Task<JsonResult> GetLocations(string loc)
{
    var locations = await _repo.GetLocationsByName(loc);

    return Json(locations);
}

Finally, the URL as reported in the 404 error looks like this:

https://[URL]/[Controller]/GetLocations?loc=Some Location

Given that the URL value isn't being found, I doubt the settings after that have anything to do with the problem. The only thing I could think to change there is that the controller was contained in a sub-folder within the Controllers folder (Controllers/myFolder/Controller), but moving the controller to the main Controllers folder, no sub-folder in between, doesn't resolve the issue.

Any advice appreciated.

EDIT: To be clear about moving the controller, I did not move it from the main Controllers folder, I only moved it out of the sub-directory within the Controllers folder in which it was previously found.

CodePudding user response:

try to remove [HttpPost], and add attribute route

[Route("~/mycontroller/GetLocations")]
public async Task<JsonResult> GetLocations(string loc)

if it is still not working try to change ajax to get

$.ajax({
     url: "/[Controller]/GetLocations?loc=" loc,
     type: "GET",
     dataType: "json",
     success: function (data, textStatus, jqXHR) {

and never ever move controllers from default Controllers folder

CodePudding user response:

Problem solved. I needed to convert my drop-down list into an @Html.DropDownListFor object, and wrap it in a form object like so:

<form id="custNameForm" asp-controller="myController" asp-action="GetLocations" method="post">
     @Html.AntiForgeryToken()

     @Html.DropDownListFor(x => x.Name, new SelectList((List<string>)ViewBag.custList), "Select Customer",
          new { @ })
</form>

Next, in my javascript file, I add the following "change" listener:

.on('change', '#CustName', function (e) {
     e.preventDefault();
     GetLocations(e);
})

...which points to this jquery function:

function GetLocations(e) {
    var loc = $('#CustName option:selected').val();
    var noLoc = loc === '' || loc === 'Select Customer';

    if (!noLoc) {
        var form = $('#custNameForm');
        var url = form.attr('action');
        var token = $('input[name="__RequestVerificationToken"]').val();

        $.ajax({
            url: url,
            type: "POST",
            dataType: "json",
            data: {
                __RequestVerificationToken: token,
                'loc': loc
            },
            success: function (data, textStatus, jqXHR) {

                var listData = data;
                resetLocationList();
                for (var listSize = 0; listSize < listData.length; listSize  ) {
                    $('#custLocation').append('<option value="'   listData[listSize]   '">'   listData[listSize]   '</option>');
                }

            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log('Error caught: ');
                console.log(errorThrown);
            }
        });
    }
    else {
        parseXML('');
    }

    $('#custLocation').prop('disabled', noLoc);
}

... where "#custLocation is the ID of the dropdown to be populated with the list of customer locations.

  • Related