Setting an alternate controller folder location in ASP.NET MVC
You can do this using Routing, and keeping the controllers in separate namespaces. MapRoute lets you specify which namespace corresponds to a route.
Example
Given this controllers
namespace CustomControllerFactory.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return new ContentResult("Controllers");
}
}
}
namespace CustomControllerFactory.ServiceControllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return new ContentResult("ServiceControllers");
}
}
}
And the following routing
routes.MapRoute(
"Services",
"Services/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "CustomControllerFactory.ServiceControllers" } // Namespace
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "CustomControllerFactory.Controllers"} // Namespace
);
You should expect the following responses
/Services/Home
ServiceController
/Home
Controllers
In Asp.Net Core: I used AreaFeature library ServiceCollectionExtensions
First set your middleware;
services.AddMvc(options =>
options.EnableEndpointRouting = false).
AddFeatureFolders().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest);
In the extenssion:
return AddFeatureFolders(services, new FeatureFolderOptions());
implement as according your requirement:
public static IMvcBuilder AddFeatureFolders(this IMvcBuilder services, FeatureFolderOptions options)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (options == null)
throw new ArgumentException(nameof(options));
var expander = new FeatureViewLocationExpander(options);
services.AddMvcOptions(o => o.Conventions.Add(new FeatureControllerModelConvention(options)))
.AddRazorOptions(o =>
{
o.ViewLocationFormats.Clear();
o.ViewLocationFormats.Add(options.FeatureNamePlaceholder + @"\{0}.cshtml");
o.ViewLocationFormats.Add(options.FeatureNamePlaceholder + @"\_Views\{0}.cshtml");
o.ViewLocationFormats.Add(options.FeatureFolderName + @"\Shared\{0}.cshtml");
o.ViewLocationFormats.Add(options.DefaultViewLocation);
o.ViewLocationExpanders.Add(expander);
});
return services;
}
In my case i preferred a separated _View folder for views in the features folders like that
~/Features/Account/_Views/login.cshtml
~/Features/Account/AccountController.cs
~/Features/Account/AccountModel.cs