ASP.NET MVC Beta - Grouping Controllers and Views possible?
-
04-07-2019 - |
Question
I am on the way to build an ASP.NET MVC application with the latest beta release and I wonder if it is possible to change the default project Layout of
/Views/Home/Index.aspx /Views/Home/About.aspx
to
/Blog/Views/Home/Index.aspx /Blog/Views/Home/About.aspx
/Forum/Views/Home/Index.aspx /Forum/Views/Home/About.aspx
The goal is to get some separation between "applications" within one single Web project, something like Thomas Owens asked already here: Under an MVC framework, which directory structure would be expected by other developers?
Of course this should include the Controllers as well, not only the Views.
Solution
This is not a new concept. It is called "areas" in Monorail. There has been a lot of buzz about this topic lately on the ATL.NET forum and elsewhere. Steve Sanderson has come up with a way to do this but apparently it leaves some issues. In reseponse, apparently the MVC team is going to take a "deep look" at it for a future release.
OTHER TIPS
Yes, it should be possible to do this. I can think of one way; there may be others.
The first step is to modify the default route to include your application name:
routes.MapRoute("Default",
"{applicationName}/{controller}/{action}/{id})",
null, null);
I'm presuming that you're going to group the two "applications" into different namespaces within a single assembly. So you might have two namespaces like:
- MyApp.Blog.Controllers
- MyApp.Forum.Controllers
Next, you need to change the controller factory so that it instantiates the right controller. You can do this by subtyping the DefaultControllerFactory and overriding the GetControllerType method:
protected override System.Type GetControllerType(string controllerName)
{
string applicationName;
if (RequestContext != null &&
RequestContext.RouteData.Values.TryGetValue(
"applicationName", out applicationName)) {
// return controller type using app name to
// look up namespace and controllerName argument
return ...
}
// if no match, maybe it's a different controller/route
return base.GetControllerType(controllerName);
}
Finally, you need to tell MVC to use your ControllerFactory. In Global.asax.cs:
private void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(
MyApp.MyControllerFactory());
}
Locating views can be handled similarly. In this case, you subtype WebFormViewEngine.
I just wrote a blog post that describes one approach to grouping controllers that's similar to "areas" in monorail. It doesn't address nested areas yet though.
http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx