Reputation: 16276
I am making Areas for User, Admin, Shop, Forum... etc
In each area, it has its own Controllers, Models, Views folders. At the root Models, root Controllers and root Views I have shared components in them.
Structure A:
Root/ -> Models/, Controllers/, Views/
Root/User/ -> Models/, Controllers/, Views/
Root/Admin/ -> Models/, Controllers/, Views/
Root/Shop/ -> Models/, Controllers/, Views/
Root/Forum/ -> Models/, Controllers/, Views/
I maybe wrong, but they really don't look DRY to me to repeat M V and C folders in each of the business logic groups. I was thinking a better structure would be using M V and C as the main folders and layout my business logic groups in them:
Structure B:
Root/Views/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Models/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Controllers/ -> User/, Admin/, Shop/, Forum/ ...etc
But if I do structure the folders this way, I lost the area (or from users point of view, the sub folder path) ability to divde logical functionalities of the website.
e.g.
with structure A, I can do:
www.mywebsite.com/Users(area)/Account(controller)/LogOn(action)
www.mywebsite.com/Admin(area)/Account(controller)/LogOn(action)
Notice I can have same controller and action names with different areas.
With structure B, best I can do is:
www.mywebsite.com/AdminAccount(controller)/LogOn(action)
www.mywebsite.com/UserAccount(controller)/LogOn(action)
It can not achieve the single-word sub-folder result without area. If not only that, the controller names here can get longer and more messy very soon. Not to mention you have a large group of actions stacking in same controller.cs file.
So, anyway, my point is, if I find Structure B making more sense to me, how do I go about configuring routing to achieve that?
Upvotes: 0
Views: 221
Reputation: 5261
So you want Structure B with url's corresponding to A?
You'll be giving up convention over configuration.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"UserAccount", // Route name
"users/account/{action}/{id}", // URL with parameters
new { controller = "UserAccount", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Another option would be to write a custom route handler and introduce your own convention. Something like the following (new convention would be to concatenate Users and Account to get the UsersAccountController in www.mywebsite.com/Users/Account/LogOn). I did not test to see how this handles areas, but if you have issues let me know and I can take a look.
public class CustomConventionRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
{
string controller = requestContext.RouteData.Values["controller"].ToString();
object controllerModifier;
if (requestContext.RouteData.Values.TryGetValue("controllerModifier", out controllerModifier))
{
requestContext.RouteData.Values["controller"] = string.Concat(controllerModifier, controller);
}
return base.GetHttpHandler(requestContext);
}
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
new Route(
"{controllerModifier}/{controller}/{action}",
new RouteValueDictionary(new { controllerModifier = UrlParameter.Optional, controller = "Home", action = "Index" }), //defaults
new CustomConventionRouteHandler()));
}
Upvotes: 1