I would like to set up a route that submits to a controller with a prefixed action.
For example, I have a ProvidersController
for service providers, and I have a ProviderType
model that I'd like to handle within the Providers controller (it's a lightweight object and I just assume not set up new controllers specifically for each of these little supporting objects, thus I want to group them into the Providers controller).
So, my ProvidersController
has standard actions for managing providers:
public class ProvidersController : ControllerBase
{
public ActionResult Index() { }
public ActionResult Create() { }
public ActionResult Edit(int id) { }
// ect ect
}
I'd like to handle ProviderTypes in here as well:
public class ProvidersController : ControllerBase
{
public ActionResult Index() { }
public ActionResult Create() { }
public ActionResult Edit(int id) { }
// ect ect
public ActionResult TypeIndex() { }
public ActionResult TypeCreate() { }
public ActionResult TypeEdit(int id) { }
// ect ect
}
This is all fine, expect I want my routing to "look like" a Type is nested:
~/Providers/Create
~/Providers/Types/Create
Here's a route I had in mind:
routes.MapRoute(
name: "ProviderTypes",
url: "Providers/Types/{action}/{id}",
defaults: new { controller = "Providers", action = "Index", id = UrlParameter.Optional }
);
But this would require I use a ~/Providers/Types/TypeCreate
route, which I don't like.
Is there some way I can "intercept" this route and add a "Type" prefix to the action so it maps to the controller action correctly but provides a clean URL the way I'd like?
E.g., how would I get ~/Providers/Types/Create
to map to ProvidersController.TypeCreate()
?
(as a general note, I'm trying to avoid attribute routing as I like to have all my route definitions coming from one place instead of scattered throughout)
You could enable ASP.NET MVC Attribute Routing
in RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes){
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//enabling attribute routing
routes.MapMvcAttributeRoutes();
//You can also combine attribute routing with convention-based routing.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Then in your ProvidersController
[RoutePrefix("Providers"]
public class ProvidersController : ControllerBase {
//eg: GET Providers
[Route("")]
public ActionResult Index() {...}
//eg: GET Providers/Create
[Route("Create")]
public ActionResult Create() {...}
//eg: GET Providers/Edit/5
[Route("Edit/{id:int}")]
public ActionResult Edit(int id) {...}
// ...
//eg: GET Providers/Types
[Route("Types")]
public ActionResult TypeIndex() {...}
//eg: GET Providers/Types/Create
[Route("Types/Create")]
public ActionResult TypeCreate() {...}
//eg: GET Providers/Types/Edit/5
[Route("Types/Edit/{id:int}")]
public ActionResult TypeEdit(int id) {...}
// ...
}