I want to create controllers action from database (ASP.NET MVC 6 vNext). I have table controller and also actions action table has properties { ViewPath, ActionName }
Where actionName is {Controller}/{ActionName}
I want build pages like this. How can i make it? I have class for MVC 4 but I need to rewrite it to MVC 6
public class ITSDefaultController : DefaultControllerFactory
{
public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
try
{
return base.CreateController(requestContext, controllerName) as Controller;
}
catch (Exception)
{
Controller controller = new ITSControllerBase();
using (var db = new ITS.Database.DatabaseDataContext())
{
string action = requestContext.RouteData.Values["action"] as string;
DynamicAction dynamicAction = null;
if (!db.Controllers.Any(x => x.ControllerName == controllerName && x.Views.Any(v => v.ViewName == action)))
{
dynamicAction = Actions["NotFound"].First();
requestContext.RouteData.Values["controller"] = "NotFound";
requestContext.RouteData.Values["action"] = "Index";
}
else
{
dynamicAction = new DynamicAction()
{
ActionName = db.Views.First(d => d.ViewName == action && d.Controller.ControllerName == controllerName).ViewName,
Result = () => new ViewResult()
};
}
if (dynamicAction != null)
{
controller.ActionInvoker = new DynamicActionInvoker() { DynamicAction = dynamicAction };
}
return controller;
}
}
}
public override void ReleaseController(IController controller)
{
base.ReleaseController(controller);
}
public static ConcurrentDictionary> Actions = new ConcurrentDictionary>();
}
actually I have the same need to replace Mvc pipeline components by some custom ones, and I found that the IControllerFactory and IControllerActivator and their default implementations still the same, then the experience was to replace the Mvc 6 DefaultControllerFactory by the CustomControllerFactory, I've done some tests on the startup class on ConfigureServices :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var serviceDescriptor = services.FirstOrDefault(s => s.ServiceType.FullName.Contains("IControllerFactory"));
var serviceIndex = services.IndexOf(serviceDescriptor);
services.Insert(serviceIndex, new ServiceDescriptor(typeof(IControllerFactory), typeof(CustomControllerFactory), ServiceLifeTime.Singleton));
services.RemoveAt(serviceIndex + 1);
}
and it s done, also you can add an extension method to the IServiceCollection interface:
public static class ServiceCollectionExtensions
{
public static void(this IServiceCollection services, Type serviceType, Type implementationType, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
{
var serviceDescriptor = services.FirstOrDefault(s => s.ServiceType == serviceType);
var serviceIndex = services.IndexOf(serviceDescriptor);
services.Insert(serviceIndex, new ServiceDescriptor(serviceType, implementationType, serviceLifetime));
services.RemoveAt(serviceIndex + 1);
}
}
after this modification you can use it as simple as this :
......
services.AddMvc();
services.ReplaceService(typeof(IControllerActivator), typeof(CustomControllerActivator));
services.ReplaceService(typeof(IControllerFactory), typeof(CustomControllerFactory));
......
then you can replace any component on the Mvc 6 Pipeline;
public class HomeController : Controller
{
public string _MyName { get; set; }
// GET: Home
public ActionResult Index()
{
return Content(_MyName);
}
public HomeController(string Name)
{
_MyName = Name;
}
}
public class MyCustomController : IControllerFactory
{
public IController CreateController(RequestContext requestContext, string controllerName)
{
HomeController objHomeController = new HomeController("Any thing Which you want to pass/inject.");
return objHomeController;
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
IDisposable disposable = controller as IDisposable;
if(disposable!=null)
{
disposable.Dispose();
}
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MyCustomController());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.