Reputation: 13302
I've reorganized my project into a more logical hierarchy:
-Controllers
-Accounts
-CustomersController
-Setup
-SystemDefaultsController
-SettingsController
-HomeController
At the moment, I'm just trying to set up my URLs to match this structure. So valid example URLs would be:
localhost:1234/Home/Index
localhost:1234/Setup/SystemDefaults/Index
localhost:1234/Setup/Settings/Index
localhost:1234/CustomerAccounts/Index
So I added a route on top of the default route in RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();
//AreaRegistration.RegisterAllAreas();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Setup",
url: "Setup/{controller}/{action}/{id}",
defaults: new { controller = "Setup", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MVCWeb.Controllers.Setup" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MVCWeb.Controllers" }
);
}
This does make the above URLs work, but it has no constraints so these URLs work when I want them to be invalid:
localhost:1234/Setup/CustomerAccounts/Index localhost:1234/SystemDefaults/Index
Additionally, since the Setup route matches everything, if I do either of these:
@Html.ActionLink("Customer Accounts", "Index", "CustomerAccounts")
@Url.Action("Index", "CustomerAccounts")
It generates the URL as /Setup/CustomerAccounts/Index
instead of /CustomerAccounts/Index
.
Is there a way to do accomplish this without using an Area while still using {controller} in the route URL? Or would I have to add a route specifically for each controller under Setup?
Upvotes: 2
Views: 614
Reputation: 5847
Have you ever evaluated Attribute Routing in MVC 5? It seems like you're starting a new project, so this could be a good new start. With the [RoutePrefix]
attribute, you could probably enforce what you want to achieve easily:
[RoutePrefix("accounts")]
public class CustomersController : Controller
{
// ...
}
We don't use Attribute Routing yet so I can't speak from own experience but it looks very flexible and promising.
I created a GIST for you where I explain how you could validate your Attributes, not during compile time, but with Unit Tests. This is a simple code snipped designed for MS Test. The validation possibilities are very broad.
Custom Logic we might add to a custom RoutePrefixAttribute
? For example, the RoutePrefixAttribute allows a string as a parameter. You could rewrite it to allow only a specific Enum
as parameter, which lists only possible values, and internally set the Prefix
string.
Upvotes: 2