Reputation: 2072
Trying to get my head around Web API routing.
I have the following two controllers which have different methods/actions
public class MerchantController : ApiController
{
[HttpGet]
[ActionName("GetSuggestedMerchants")]
public IEnumerable<Merchant> GetSuggestedMerchants(string name)
{
....
and
public class PortalMerchantController : ApiController
{
[HttpGet]
[ActionName("GetNPortalMerchants")]
public IEnumerable<PortalMerchantDto> GetNPortalMerchants(int id)
{
...
And I have these two routes mapped:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApiTwoParams",
routeTemplate: "api/{controller}/{action}/{name}"
);
Calling
$http.get("api/PortalMerchant/GetNPortalMerchants/26")
works fine but calling
$http.get("api/Merchant/GetSuggestedMerchants/SomeName")
does not get routed and fails with:
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:2769/api/Merchant/GetSuggestedMerchants/SomeName'.","MessageDetail":"No action was found on the controller 'Merchant' that matches the request."}
I figured I needed two roots because the parameter name and type is different for the two methods. Can anyone suggest why the second one does not get routed?
Upvotes: 0
Views: 1904
Reputation: 33738
Routing take the first route that matches the URL.
Your URLs do not contain named parameters.. just parameter values.
You need to define stricter routeTemplate
s. Like:
config.Routes.MapHttpRoute(
name: "PortalMerchantAPI",
routeTemplate: "api/PortalMerchant/{action}/{name}"
);
config.Routes.MapHttpRoute(
name: "MerchantAPI",
routeTemplate: "api/Merchant/{action}/{id}"
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
The order of the routes matters
Upvotes: 2