En mi aplicación, tengo un menú desplegable que enumera varios clientes y un segundo menú desplegable que enumera las ciudades con las que está asociado un cliente determinado. La selección de un cliente debe completar el segundo menú desplegable con la lista de ubicaciones correspondiente. Esto sucede al activar una llamada Ajax a un método en el controlador, que pasa el nombre del cliente seleccionado en la variable "loc". La lista de ubicaciones se obtiene a través de una consulta de EF Core.
Todo esto funciona como se esperaba en mi máquina local, pero cuando se ejecuta en nuestro servidor devuelve un error 404 - No encontrado.
La llamada de Ajax se ve así:
$.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); } });Y el método en el controlador se ve así:
[HttpPost] public async Task<JsonResult> GetLocations(string loc) { var locations = await _repo.GetLocationsByName(loc); return Json(locations); }Finalmente, la URL como se informa en el error 404 se ve así:
https://[URL]/[Controller]/GetLocations?loc=Some%20LocationDado que no se encuentra el valor de la URL, dudo que la configuración posterior tenga algo que ver con el problema. Lo único que se me ocurrió cambiar allí es que el controlador estaba contenido en una subcarpeta dentro de la carpeta Controladores (Controladores/miCarpeta/Controlador), pero mover el controlador a la carpeta Controladores principal, sin subcarpetas intermedias, no no resolver el problema.
Cualquier consejo apreciado.
EDITAR: Para ser claro acerca de cómo mover el controlador, no lo moví de la carpeta principal de Controladores, solo lo moví fuera del subdirectorio dentro de la carpeta de Controladores en el que se encontraba anteriormente.
intente eliminar [HttpPost] y agregue la ruta de atributo
[Route("~/mycontroller/GetLocations")] public async Task<JsonResult> GetLocations(string loc)si todavía no funciona, intente cambiar ajax para obtener
$.ajax({ url: "/[Controller]/GetLocations?loc="+loc, type: "GET", dataType: "json", success: function (data, textStatus, jqXHR) {y nunca mueva los controladores de la carpeta de controladores predeterminada
Problema resuelto. Necesitaba convertir mi lista desplegable en un objeto @Html.DropDownListFor y envolverlo en un objeto de formulario así:
<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 { @class="form-control text-center" }) </form>A continuación, en mi archivo javascript, agrego el siguiente oyente de "cambio":
.on('change', '#CustName', function (e) { e.preventDefault(); GetLocations(e); })... que apunta a esta función jquery:
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); }... donde "#custLocation es el ID del menú desplegable que se completará con la lista de ubicaciones de clientes.