Кажется, контроллеры не распознаются фабрикой контроллеров

Я хочу создать фабрику контроллеров с 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 равен нулю!!!

введите описание изображения здесь

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.
}

Последнее (Initialize) является абсолютной самой ранней точкой, в которой вы можете использовать свойство ControllerContext, если только вы не обработали присвоение самостоятельно, что не рекомендуется (поскольку части каркаса будут зависеть от того, назначено ли это свойство в то время).

Источник: Null ControllerContext в моем собственном контроллере, наследуемом от BaseController

Вам придется map ваш Controllers в другом месте на основе этой новой информации.

Другие вопросы по тегам