2

I am using Web API to expose a bunch of services. I am having issue with some routes and need some help.

I have the default route defined:

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

With this route I can hit normal routes such as: '/api/clients/' and '/api/clients/4'. I would like a GET that hits the following routes 'api/clients/4/profiles' and 'api/clients/4/validations'.

I have tried the following routes without success:

config.Routes.MapHttpRoute(
    name: "ClientProfilesApi",
    routeTemplate: "api/{controller}/{clientid}/profiles",
    defaults: new { action = RouteParameter.Optional },
    constraints: new { controller = "clients" }
    );

 config.Routes.MapHttpRoute(
   name: "ClientValidationsApi",
       routeTemplate: "api/{controller}/{clientid}/validations",
       defaults: new { action = RouteParameter.Optional },
   constraints: new { controller = "clients" }
   );

I also tried using the 'ActionName' attribute as follows:

[HttpGet]
[ActionName("profiles")]
public IEnumerableResponseDto<ProfileLayoutDto> GetProfiles(Int64 clientId, [FromUri] IEnumerableRequestDto request)
{ .... }


[HttpGet]
[ActionName("profiles")]
public IEnumerableResponseDto<ValidationLayoutDto> GetValidations(Int64 clientId, [FromUri] IEnumerableRequestDto request)
{ .... }

What am I missing? Is it not possible to have multiple GETs in a controller?

j0k
  • 22,600
  • 28
  • 79
  • 90
Skadoosh
  • 2,575
  • 8
  • 40
  • 53
  • What error are you getting? – tcarvin Jan 16 '13 at 02:43
  • @tcarvin: No HTTP resource was found that matches the request URI 'http://localhost:4422/api/clients/11/profiles'. No action was found on the controller 'Clients' that matches the request. – Skadoosh Jan 16 '13 at 02:45

2 Answers2

3

For routes 'api/clients/4/profiles' and 'api/clients/4/validations', name the actions 'profiles' and 'validations' then use the following routes BEFORE the default route:

config.Routes.MapHttpRoute(
    name: "ClientProfilesApi",
    routeTemplate: "api/clients/{clientid}/profiles",
    defaults: new { controller = "clients", action = "profiles",  },
    constraints: new {clientid = @"\d+" }
    );

 config.Routes.MapHttpRoute(
    name: "ClientValidationsApi",
    routeTemplate: "api/clients/{clientid}/validations",
    defaults: new { controller = "clients", action = "validations",  },
    constraints: new {clientid = @"\d+" }       );

This means route 'api/clients/4/profiles' goes to controller 'clients' and action ' profiles' and that the parameter 'clientid' has to be an integer.

The default routes should ALWAYS be last.

viperguynaz
  • 12,044
  • 4
  • 30
  • 41
  • Is it possible to have a constraint on the action parameter? So, within my route constraints, can I do action = ("profiles|validations")? I wonder ... – Skadoosh Jan 16 '13 at 03:40
  • 1
    that will work too!. But, you don't really need a constraint just use "../{clientid}/{action}" and don't use a default action - any action that can't be found will 404 – viperguynaz Jan 16 '13 at 04:11
0

You need:

config.Routes.MapHttpRoute(
name: "ClientApi",
routeTemplate: "api/{controller}/{clientid}/{action}",
defaults: new { action = RouteParameter.Optional },
constraints: new { controller = "clients" }
);

You'll probably still need the ActionName attribute (but I'm not sure) and you might want to remove the RouteParameter.Optional default from the action unless you want to also have Get requests for (e.g):

api/clients/4

serviced by a Get action in your controller.

Eli Algranti
  • 8,707
  • 2
  • 42
  • 50
  • I have added the route before the default route and I have added the 'ActionName' attribute, but I still get the same error as before. – Skadoosh Jan 16 '13 at 03:06