gpt4 book ai didi

c# - ASP.NET MVC 6 Controller 工厂

转载 作者:太空狗 更新时间:2023-10-29 22:02:02 24 4
gpt4 key购买 nike

我想从数据库(ASP.NET MVC 6 vNext)创建 Controller Action 。我有表 Controller 和 Action 操作表具有属性 { ViewPath, ActionName } 其中 actionName 是 {Controller}/{ActionName}我想要这样构建页面。我怎样才能做到?我有 MVC 4 的类(class),但我需要将其重写为 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>();
}

最佳答案

其实我也有同样的需要将Mvc管道组件替换成一些自定义的,我发现IControllerFactory和IControllerActivator以及它们的默认实现还是一样的,然后经验就是将Mvc 6的DefaultControllerFactory替换成CustomControllerFactory,我在 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);
}

大功告成,你也可以给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);
}
}

修改后你可以像这样简单地使用它:

    ......
services.AddMvc();
services.ReplaceService(typeof(IControllerActivator), typeof(CustomControllerActivator));
services.ReplaceService(typeof(IControllerFactory), typeof(CustomControllerFactory));
......

然后就可以替换Mvc 6 Pipeline上的任何组件;

关于c# - ASP.NET MVC 6 Controller 工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31389858/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com