1

I have five actions in my web api controller as follows.

http://localhost:1234/products - to map getallproduct action
http://localhost:1234/products/1 - to map getproductnyid action
http://localhost:1234/products - saveproduct action (post)
http://localhost:1234/products/1/getcolor - getproductcolorbyid action
http://localhost:1234/products/1/getcost - getproductcostbyid action

I need only one custom routing url for this.

I have tried following routing but it appends action name in url(http://localhost:24007/product/GetProductByID/Id) which i don't want.

config.Routes.MapHttpRoute(
    name: "ProductRoute",
    routeTemplate: "product/{action}/{productId}",
    defaults: new { controller = "Product", productId= RouteParameter.Optional }
);
Nkosi
  • 191,971
  • 29
  • 311
  • 378

1 Answers1

1

You have to use Attribute Routing if you want this kind of flexibility:

[RoutePrefix("products")]
public class ProductsController : ApiController {

    [HttpGet]
    [Route("")]
    public IHttpActionResult GetAllProduct()
    {
        //...
    }

    [HttpGet]
    [Route("{productId}")]
    public IHttpActionResult GetProductById(int id)
    {
        //...
    }

    [HttpPost]
    [Route("")]
    public IHttpActionResult SaveProduct(Product product)
    {
        //...
    }

    [HttpGet]
    [Route("{productId}/getcolor")]
    public IHttpActionResult GetProductColorById(int id)
    {
        //...
    }

    [HttpGet]
    [Route("{productId}/getcost")]
    public IHttpActionResult GetProductCostById(int id)
    {
        //...
    }
}

And remember to register them in your HttpConfiguration object:

config.MapHttpAttributeRoutes();

As an aside: if you are designing a RESTful API (which it seems to me) I strongly suggest you to avoid using RPC-like actions in your URIs (e.g. never use URI segments like getcolor, getcost), but use names that conforms with REST constraints:

http://localhost:1234/products/1/color
http://localhost:1234/products/1/cost

This can be achieved by changing your RouteAttributes:

[Route("{productId}/color")]
//...
[Route("{productId}/cost")]
Federico Dipuma
  • 15,660
  • 3
  • 39
  • 52
  • Thanks. As per the requirement we should not use attribute routing –  Jun 01 '16 at 13:38
  • I'm afraid you have no other options then. – Federico Dipuma Jun 01 '16 at 13:40
  • Can you please explain why should not use urls like getcolors,getcost? –  Jun 01 '16 at 13:42
  • 1
    Any RESTful URI should only represent a resource. Actions on that resource (verbs, intents, etc.) should only be expressed using HTTP Methods (GET, POST, PUT, etc.). [This post](http://stackoverflow.com/questions/19646989/is-using-a-verb-in-url-fundamentally-incompatible-with-rest) may be useful, also [this resource](http://www.restapitutorial.com/lessons/restfulresourcenaming.html) could help furhter clarify REST APIs URI design methods. – Federico Dipuma Jun 01 '16 at 13:54