Search code examples
c#asp.net-web-api2asp.net-web-api-routing

cannot resolve routing for action


I´m creating a Web-API with a controller like this:

public class ProductsController : ApiController
{
    private readonly Product[] m_products = {
        new Product {Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1},
        new Product {Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M},
        new Product {Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M}
    };

    public IEnumerable<Product> GetAllProducts()
    {
        return this.m_products;
    }


    [HttpGet]
    [ActionName("ById")]
    public IHttpActionResult GetProductById(int id)
    {
        var product = this.m_products.FirstOrDefault(x => x.Id == id);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }

    [HttpGet]
    [ActionName("ByName")]
    public IHttpActionResult GetProductByName(string name)
    {
        var product = this.m_products.FirstOrDefault(x => x.Name == name);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }
}

Within my WebApiConfig I have this:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

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

So in fact I´m trying to have two actions on my ProductController. However I can´t seem to get the second one to work. Thuis when I run myServer/api/products/ById/1 I get the first element from my list. However when I try myServer/api/products/ByName/Hammer I get an Http-error not found (404). I also tried the URL in lowercase with the same result.


Solution

  • You can explicitly specify the pattern using Route() attribute for your action method like:

    [HttpGet]
    [ActionName("ByName")]
    [Route("api/Products/ByName/{name}")]
    public IHttpActionResult GetProductByName(string name)
    {
        var product = this.m_products.FirstOrDefault(x => x.Name == name);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }
    

    Please refer to the official documentation for more details.