Reputation: 24308
I have setup a asp.net web api project (it works exactly the same as a Mvc Project) using routing - hence i have the following
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
So everything works just the way i want it .... I enter api/Products/15 it it arrives in my Products Controller passing in 15 as the id.
Great.
I also have 2 controllers more, 1 called UploadsController and 1 called DownloadsController. These offer Uploads and Downloads (GET / PUT etc)
Now i don't want them to be picked up by the original rule (see above)
But what i would like is to use these 2 urls to access them
/api/Transport/Uploads/15 /api/Transport/Downloads/15
I have passed in 15 as the ID, probably wouldn't happen in real life... just its good for demonstration :-)
Now Transport doesn't exist so i could do the following
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/Transports/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
which i believe works...
but the problem is that if i do
/api/Uploads/15 - this would also be caught by the original rule which i don't want..
I want the Uploads and DOwnloads controller to be accessed through the fake "Transports" and not without the Transports
Can anyone help?
Thanks in advance
Upvotes: 6
Views: 3619
Reputation: 1038800
You could use route constraints and define 2 API routes in the following order:
// matches /api/transports/downloads/id or /api/transports/uploads/id only
// and no other possible controller
routes.MapHttpRoute(
name: "API Transport",
routeTemplate: "api/transports/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { controller = "uploads|downloads" }
);
// matches anything in the form /api/{controller}/id where {controller}
// could be anythnig different than "downloads" or "uploads" because we don't
// want to allow the following urls: /api/downloads/id and /api/uploads/id
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { controller = @"^((?!(downloads|uploads)).)*$" }
);
Upvotes: 18