Reputation: 36816
I have a fairly large ASP MVC application. Instead of having many controllers all in the controller directory I would rather create some hierarchy. So I might have something like
~\Controllers\Security\
~\Controllers\Maintenance\
~\Controllers\Reports\
I would also like to be able to do similar with Views
~\Views\Security\Users\
~\Views\Security\Roles\
~\Views\Maintenance\Customer\
~\Views\Maintenance\Product\
Is this easily done?
Upvotes: 3
Views: 1519
Reputation: 73
Have you considered to switch to Features Folder. I've tried it (with little modifications) and it works pretty good.
Described in this post http://timgthomas.com/2013/10/feature-folders-in-asp-net-mvc/
Code examples are in Jimmiy Bogard's repo https://github.com/jbogard/presentations/tree/master/putyourcontrollersonadietv2
Upvotes: 1
Reputation: 4432
What you really want here is for your Views folder hierarchy to match the namespace hierarchy of your controllers. You can write a custom ViewEngine to do this fairly easily - see my ControllerPathViewEngine project on GitHub for details.
I've included a snippet of the ControllerPathRazorViewEngine class to outline how it works. By intercepting the FindView / FindPartialView methods and replacing the controller name with a folder path (based on controller namespace and name), we can get it to load views from nested folders within the main Views folder.
public class ControllerPathRazorViewEngine : RazorViewEngine
{
//... constructors etc.
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
return FindUsingControllerPath(controllerContext, () => base.FindView(controllerContext, viewName, masterName, useCache));
}
public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
return FindUsingControllerPath(controllerContext, () => base.FindPartialView(controllerContext, partialViewName, useCache));
}
private ViewEngineResult FindUsingControllerPath(ControllerContext controllerContext, Func<ViewEngineResult> func)
{
string controllerName = controllerContext.RouteData.GetRequiredString("controller");
string controllerPath = controllerPathResolver.GetPath(controllerContext.Controller.GetType());
controllerContext.RouteData.Values["controller"] = controllerPath;
var result = func();
controllerContext.RouteData.Values["controller"] = controllerName;
return result;
}
}
Upvotes: 0
Reputation: 31975
The concept you're searching for is called "areas", as outlined by Phil Haack here: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx
Upvotes: 2
Reputation: 2944
I think you're looking for something like what the "master" says in this post:
http://haacked.com/archive/0001/01/01/areas-in-aspnetmvc.aspx
Basically you have to create a ViewEngine to specify where to look for the views. It's a fairly simple code, just don't forget to register it in the global.asax! As for the controller part you'll have to register new routes also in the global.asax.
Upvotes: 4
Reputation: 7693
I would think you'd need to write your own RouteHandler, which shouldn't be too tough.
A quick google search turned up: This blog post detailing it
Upvotes: 1