Owen Burns
Owen Burns

Reputation: 140

How to fix incorrect action routing in a webAPI

When calling my API through JS in a test HTML page it fails to return any result whatsoever. Doing some research, I've come to the conclusion that it either isn't finding my API controller (less likely since it returned a result using some example code but the same URI) or is finding it but not finding the correct action. The point of the application is sending a youtube search request and receiving a list of results back.

I've tried setting breakpoints throughout the code and it seems to only run through the JS on the HTML page but never actually hit the controller itself. This changed when I added a new method taking no parameters to just return the one result of a list which did return the result, but stopped working shortly after seemingly without changing anything.

This is the code in the HTML document calling the API


var uri = 'api/Search';
        function formatItem(item) {
            return item.title;
        }

        function find() {
            var word = $('#srval').val();
            $.getJSON(uri + '/' + word)
                .done(function (data) {
                    $('#product').text(formatItem(data));
                })
                .fail(function (jqXHR, textStatus, err) {
                    $('#product').text('Error: whyyyyyyyyyyyyy');
                });
        }

This is the default code used for API routing:

config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                //defaults: new { id = RouteParameter.Optional }
                defaults: new { id = RouteParameter.Optional }
            );

This is the controller method I'm trying to call

[HttpGet]
        public IHttpActionResult GetSearch(string search)
        {
            getyoutuberesults(search);
            var results = searcheslist;
            return Ok(results);
        }

and the name of the search controller as it appears in the code with the methods therein removed:

public class SearchController : ApiController
    {
...
}

The expected result is that the HTML tag 'product' is filled with results for a YouTube search for the value of HTML tag 'srval'.

Instead, the page just freezes upon hitting the search button and as stated above seemingly never even reaches the GetSearch method. Going directly to the URI localhost:44345/api/Search/[search term] results in the following error message:

No HTTP resource was found that matches the request URI 'https://localhost:44345/api/Search/test'. No action was found on the controller 'Search' that matches the request.

Upvotes: 2

Views: 579

Answers (1)

Nkosi
Nkosi

Reputation: 247018

The route template parameter names do not match. The default convention route has {id} while the controller action has search parameter. Which cause matches for the desired action to not be found (404).

Consider using attribute routing by first enabling it

// Attribute routing.
config.MapHttpAttributeRoutes(); //<---THIS HERE BEFORE CONVENTION BASED ROUTING

// Convention-based routing.
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

and decorating the controller accordingly

[RoutePrefix("api/search")]
public class SearchController : ApiController {

    //...

    //GET api/search/word
    [HttpGet]
    [Route("{search}")]
    public IHttpActionResult GetSearch(string search) {           
        var results = getyoutuberesults(search);
        return Ok(results);
    }

    //...
}

Reference Attribute Routing in ASP.NET Web API 2

Upvotes: 4

Related Questions