Web Api multiple get with same signature routing

asp.net-mvc, asp.net-mvc-4, asp.net-web-api

Solution

Here's the answer I found and it does pretty much exactly what I wanted:

        config.Routes.MapHttpRoute(
            name: "VenuesAllOrStream",
            routeTemplate: "api/Racing/{action}",
            defaults: new { controller = "Racing", action = "Venues" },
            constraints: new { action = "Venues|All|Streaming" }
        );

        config.Routes.MapHttpRoute(
            name: "VenueOrVideo",
            routeTemplate: "api/Racing/{venue}/{action}",
            defaults: new { controller = "Racing", action = "RaceNumbers" },
            constraints: new { action = "RaceNumbers|Video" }
        );

        config.Routes.MapHttpRoute(
            name: "ProgramOrMtp",
            routeTemplate: "api/Racing/{venue}/{race}/{action}",
            defaults: new { controller = "Racing", action = "Program" },
            constraints: new { action = "Program|Mtp", race = @"\d+" }
        );

It is important that the VenuesAllOrStream is first as otherwise the VenueOrVideo picks up the route. I most likely will extract out the action constraints into enums later.

Brief note : Setting the action default allows for the route to basically make it an optional parameter. So each route works without the {action} actually being set.

Problem

I'm building a web api that has multiple get/post calls that have the same signatures. Now I know that in the case of multiple identical calls, you generally have 2 options: separate into different controllers, or use {action} in your routes. I have gone the {action} method as it fits best I believe in most of my controllers. However, in one of my controllers I would prefer not to use the action method. I have a call like so: ``` [HttpGet] public Program Program(string venue, string eventId) //api/{controller}/{venue}/{eventId} ``` Now I need a new call ``` [HttpGet] public Program ProgramStartTime(string venue, string eventId) //api/{controller}/{venue}/{eventId} ``` I know I can add an action name to this and call i.e ``` api/{controller}/{action}/{venue}/{eventId} ``` But I feel like it breaks the expected. Is there a way that I could some something like ``` api/Content/LAA/1/PST api/Content/LAA/1?PST ``` Also if I have to go the action route, I currently already have a route I use for other controllers, but it simply uses {id} as its only parameter. Will a new route conflict with this one? Is there a better way to setup my routes? ``` config.Routes.MapHttpRoute( name: "...", routeTemplate: "api/{controller}/{action}/{id}", defaults: new {id = RouteParameter.Optional} ); config.Routes.MapHttpRoute( name: "...", routeTemplate: "api/{controller}/{action}/{venue}/{eventId}/{...}/{***}/{###}", defaults: new {### = RouteParameter.Optional} ); config.Routes.MapHttpRoute( name: "...", routeTemplate: "api/{controller}/{action}/{venue}/{eventId}/{...}", defaults: new {... = RouteParameter.Optional} ); config.Routes.MapHttpRoute( name: "...", routeTemplate: "api/{controller}/{action}/{venue}", defaults: new {venue = RouteParameter.Optional} ); ``` I expect at least one method that would have up to 5 parameters

Original source