我在最后一个mvc版本5.2.6上分离了两个项目的控制器和视图
我们有许多具有相同控制器的客户端项目,但有时需要覆盖控制器。
我会这样做: 我的库项目中的默认控制器,但如果我们在主项目中找到控制器,请使用这个控制器。
但是当我这样做时:
ControllerBuilder.Current.DefaultNamespaces.Add("MainProject.Controllers");
ControllerBuilder.Current.DefaultNamespaces.Add("Library.Controllers");
我得到一个错误控制器是不明确的
理念是为所有客户网站提供通用控制器。客户端网站将仅包含视图,但需要覆盖某些控制器以用于特定的客户端开发。
答案 0 :(得分:0)
在我的例子中,我有两个类似的控制器。一个在Core命名空间中,一个在Client中:
namespace CustomControllerFactory.Core.Controllers
{
public class DemoController : Controller
{
public ActionResult Index()
{
ViewBag.CalledFrom = "Core";
return View();
}
}
}
namespace CustomControllerFactory.Client.Controllers
{
public class DemoController : Controller
{
public ActionResult Index()
{
ViewBag.CalledFrom = "Client";
return View();
}
}
}
为此,我创建了一个自定义控制器工厂:
public class CustomControllerFactory : IControllerFactory
{
public IController CreateController(RequestContext requestContext, string controllerName)
{
var ns = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
var coreNs = $"{ns}.Core.Controllers";
var clientNs = $"{ns}.Client.Controllers";
//find out if core or client exists: https://stackoverflow.com/questions/8499593/c-sharp-how-to-check-if-namespace-class-or-method-exists-in-c
var coreControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == coreNs
select type);
var clientControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == clientNs
select type);
Type controllerFullType = null;
if (coreControllers.Any(x => x.Name == $"{controllerName}Controller"))
{
controllerFullType = Type.GetType($"{ns}.Core.Controllers.{controllerName}Controller");
}
else if (clientControllers.Any(x => x.Name == $"{controllerName}Controller"))
{
controllerFullType = Type.GetType($"{ns}.Client.Controllers.{controllerName}Controller");
}
else
{
throw new ApplicationException("no valid controller found");
}
IController controller = Activator.CreateInstance(controllerFullType) as Controller;
return controller;
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
(controller as IDisposable)?.Dispose();
}
}
执行以下操作:
然后你必须在global.asax中注册你的工厂:
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));