Search code examples
jqueryajaxasp.net-coreasp.net-core-webapiasp.net-core-routing

jQuery Ajax GET calling wrong method in Web API Core controller


I'm doing a simple get call but I can't seem to get the correct GET method to trigger in my Web API Controller. My route is as follows:

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

    // I already tried removing this, same result
    routes.MapSpaFallbackRoute("spa-fallback", 
        new { controller = "Home", action = "Index" });
});

and my Controller containing the GET methods (in that sequence):

[Route("api/[controller]")]
[ApiController]
public class SchoolYearsController : ControllerBase
{
    [HttpGet("~/api/terms/{termId:int}")]
    public IActionResult GetTermById(int termId)
    {
        // omitted for brevity
    }

    [HttpGet("~/api/terms")]
    public IActionResult GetAllTerms()
    {
        // omitted for brevity
    }
}

and my ajax call:

loadTerm() {
    $.ajax({
        url: "/api/terms?termid=3",
        method: "GET",
        contentType: "application/json; charset=utf-8"
    })
    .done((response, textStatus, xhr) => {
        // omitted for brevity
    })
    .fail((xhr, textStatus, errorThrown) => {
        console.log(errorThrown);
    });
}

These are the relevant sections, I think. For some reason, it is always calling the 2nd method ("~/api/terms") instead of the one with termId parameter. Any ideas on what's happening?


Solution

  • The route template for that GetTermById action expects the termId in the route not in a query string.

    Note the comment in the code.

    //GET /api/terms/3
    [HttpGet("~/api/terms/{termId:int}")]
    public IActionResult GetTermById(int termId) {
        // omitted for brevity
    }
    

    So that means that if the requested URL does not match the expected route template that it will not call that action. The GetAllTerms action expects /api/terms, which matches the call being made by the client, even with the query string, as route template is not taking the query string into account when mapping the action in this case.

    Update client call

     url: "/api/terms/3",
    

    Reference Routing to controller actions in ASP.NET Core