AaBa
AaBa

Reputation: 471

Routing issue with overloaded Get method in WebAPI

I have 2 Get methods in Product controller as below:

public IHttpActionResult Get(string keywordSearch)

[Route("api/Product/{id:long}")]
public IHttpActionResult Get(long id)

The following url works:

http://localhost:61577/api/Product?keywordSearch=test
http://localhost:61577/api/Product/1

This one fails, with message:

http://localhost:61577/api/Product/test

{    
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:61577/api/Product/test'.",
"MessageDetail": "No action was found on the controller 'Product' that matches the request."
}

The WebApiConfig.cs has following configurations:

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

Please advice, what changes should I make in API function or Config to make that work.

Upvotes: 0

Views: 429

Answers (1)

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

You would need to specify the routes in your routes configuration for both the action methods something like:

// for number type parameter only
config.Routes.MapHttpRoute(
    name: "IdSearch",
    routeTemplate: "api/{controller}/{id}",
    defaults: null,
    constraints: new { id = @"^\d+$" } // Only integers 
);

and then register another one for string parameter :

// for string parameter overload action route
config.Routes.MapHttpRoute(
    name: "KeyWordSearch",
    routeTemplate: "api/{controller}/{keywordSearch}",
    defaults: null
);

and in your action declaration apply propery attribute values on string parameter overload one, so that both will look like:

[Route("api/Product/{keywordSearch}")]
public IHttpActionResult Get(string keywordSearch)

[Route("api/Product/{id:long}")]
public IHttpActionResult Get(long id)

Another way is that you can use the RoutePrefix on your Controller class and then the Route attribute on your action methods, so that you don't have to duplicate the Prefix of Route on each action method:

[RoutePrefix("api/product")] 
public class ProductController : ApiController
{
    [Route("{keywordSearch}")] 
    public IHttpActionResult Get(string keywordSearch)

    [Route("{id:long}")]
    public IHttpActionResult Get(long id)
}

This should keep you going.

Hope it helps!

Upvotes: 2

Related Questions