0

我想用 Autofac 创建一个控制器工厂,但在这一行中出现空引用实例错误:string ctrName = contr.ControllerContext.RouteData.Values["Controller"].ToString() 当我运行我的项目时。

这是我的controller factory

internal class ControllerFactory : DefaultControllerFactory
{
    private readonly Dictionary<string, Func<RequestContext, IController>> _controllerMap;

    public ControllerFactory()
    {
        List<IController> lstControllers = DependencyResolver.Current.GetServices<IController>().ToList();
        _controllerMap = new Dictionary<string, Func<RequestContext, IController>>();

        foreach (Controller contr in lstControllers)
        {
            string ctrName = contr.ControllerContext.RouteData.Values["Controller"].ToString();  //iv got null instance error in this line
            _controllerMap.Add(ctrName, c => contr);
        }
    }

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {

        if (_controllerMap.ContainsKey(controllerName))
        {
            return _controllerMap[controllerName](requestContext);
        }
        else
            throw new KeyNotFoundException(controllerName);
    }
}

这是我的appstart:

        protected void Application_Start()
    {

        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly).AsImplementedInterfaces();

        builder.Register(s => new ControllerFactory()).As<IControllerFactory>();


        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));


        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

错误原因很清楚:ControllerContext我的 foreach 项目为空……但为什么呢?我的解决方案中有控制器:

   public class HomeController : Controller 
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";

        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }

}

更新:我在 foreach 上检查了调试器。项目类型是WebApplication1.Controllers.HomeController指我的家庭控制器,但 mt 项目的控制器上下文为空!

在此处输入图像描述

4

1 回答 1

1

这意味着您可以访问 ControllerContext 属性的最早点是通过覆盖 Execute 或 Initialize 方法(但首先调用 base.Execute 或 base.Initialize):

protected override void Execute(RequestContext requestContext)
{
  base.Execute(requestContext);

  // .ControllerContext is available from this point forward.
}

protected override void Initialize(RequestContext requestContext)
{
  base.Initialize(requestContext);

  // .ControllerContext is available from this point forward.
}

后者(初始化)是您可以使用 ControllerContext 属性的绝对最早点,除非您自己处理分配,否则不建议这样做(因为框架的一部分将取决于当时分配的该属性)。

来源:从 BaseController 继承的自定义控制器中的 Null ControllerContext

根据这些新信息,您将不得不前往map您的其他地方。Controllers

于 2017-03-07T15:01:01.760 回答