1

I have web api 2 controller actions:

 [HttpGet] public Response<IEnumerable<Product>> Get() { ....(Get all products) } [HttpGet] public Response<Product> Get(int id) { ....(Get product by id) } [HttpGet] public Response<IEnumerable<Product>> Category(int id) { .... (Get products by category) } 

I want to use this controllers with url:

http://localhost/api/product http://localhost/api/product/1 http://localhost/api/product/category/1 

But this url http://localhost/api/product/1 returns error,

Multiple actions were found that match the request

My config settings are like this:

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

3 Answers 3

1

You might be better off using attribute routing rather than global routing here. If you remove your global routes and define your routes on a per-action basis you should have no problems. For example, your routes could look like:

[Route("api/product")] [Route("api/product/{id:int}")] [Route("api/product/category/{id:int}")] 
Sign up to request clarification or add additional context in comments.

Comments

0

This is the default controller created when you create a new ASP.NET Web APi within Visual Studio:

[Authorize] public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } } 

And the WebApi config:

public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } 

Comments

0

Your two Get methods match the same route. I would delete the first Get method and change your second Get method to use an optional id parameter like so:

[HttpGet] public Response<IEnumerable<Product>> Get(int? id) { // Get all products if id is null, else get product by id and return as a list with one element } 

This way, Get will match routes for both "product" and "product/1".

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.