1
votes

I am using Sitecore v9

I have a two base class for all my controllers as follows

public abstract SiteCoreController : ControllerBase, IController, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IAsyncManagerContainer

public abstract class ControllerBase : IController

All controllers use something like

public class MyPageController : SiteCoreController 

In my log files I get heaps of errors

Sitecore.Mvc.Diagnostics.ControllerCreationException: Could not create controller: The context item is: '/sitecore/content/TEST/home'. The current route url is: '{*pathInfo}'. This is the default Sitecore route which is set up in the 'InitializeRoutes' processor of the 'initialize' pipeline. ---> Sitecore.Mvc.Diagnostics.ExceptionWrapper: The controller for path '/' was not found or does not implement IController. at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) at Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName) --- End of inner exception stack trace --- at Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName) at Sitecore.Mvc.Controllers.ControllerRunner.GetController() at Sitecore.Mvc.Controllers.ControllerRunner.Execute() at Sitecore.Mvc.Pipelines.Request.RequestBegin.ExecuteFormHandler.ExecuteHandler(String controllerName, String actionName, RequestBeginArgs args) at (Object , Object[] ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args) at Sitecore.Mvc.Routing.RouteHttpHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

My DI is setup as follows

public static void SetupControllers(this IServiceCollection serviceCollection, params Assembly[] assemblyArray)
{
    var controllers = GetTypesImplementing<IController>(assemblyArray)
        .Where(controller => controller.Name.EndsWith("Controller", StringComparison.Ordinal));

    foreach (var x in controllers)
    {
        serviceCollection.AddTransient(x);
    }

    var apis = GetTypesImplementing<ApiController>(assemblyArray)
        .Where(controller => controller.Name.EndsWith("Controller", StringComparison.Ordinal));

    foreach (var x in apis)
    {
        serviceCollection.AddTransient(x);
    }
}
2
Show the controller causing the problem. Does it have dependencies? Have they all been registered correctly? Most times this happens because the controller factory was unable to resolve all the necessary dependencies to the controller.Nkosi

2 Answers

0
votes

It sounds like you might have forgotten to register the controller in Sitecore DI container.

Here is an example (Option 1: Just use Sitecore’s Container).

In our project we've created a dummy ControllerAttribute attribute to put on controllers we need to be automatically created.

Next - own Configurator that registers types from the namespace to DI, like:

var enumerable = from type in assemblies.Where((Assembly assembly) => !assembly.IsDynamic).SelectMany(GetExportedTypes)
    where !type.IsAbstract && !type.IsGenericTypeDefinition
    select new
    {
        Lifetime = type.GetCustomAttribute<ControllerAttribute>()?.Lifetime,
        ServiceType = type,
        ImplementationType = type.GetCustomAttribute<ControllerAttribute>()?.ControllerType
    } into t
    where t.Lifetime.HasValue
    select t;
foreach (var item in enumerable)
{
    if (item.ImplementationType == null)
    {
        serviceCollection.Add(item.ServiceType, item.Lifetime.Value);
    }
    else
    {
        serviceCollection.Add(item.ImplementationType, item.ServiceType, item.Lifetime.Value);
    }
}
0
votes

Not sure if it's relevant for anyone but I'll post how I fixed it:

Background

  1. Sitecore 9.2 using GlassMapper & Microsoft DI.
  2. Helix solution pattern.

Problem

All my controllers were loading except 2. After grinding my head for few hours noticed there were spelling mistakes in those 2 controllers.

Solution

Changed controller mis-spelled name PersonalizationContoller to PersonalizationController

As I understand due to the 'r' missing in the controller name, the DI was not considering it as a controller thus not registered. Simply go to /sitecore/admin/showservicesConfig.aspx & check if your controller is registered - if not then either the name is wrong or the controller is using dependencies not loaded.