SaaS CMS has officially launched! Learn more now.

Problems upgrading to CMS 12

Vote:
 

Hello

I'm trying to upgrade a site from cms 11 to latest cms 12, but I'm getting an error when trying to start the site.

Startup.cs:

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(name: "Default", pattern: "{controller}/{action}/{id?}");
                endpoints.MapControllers();
                endpoints.MapContent(); //      <----- boom
                endpoints.MapRazorPages();                
            });

Message: Unable to find a module by assembly 'Abcde.Web, Version=4.26.9.0, Culture=neutral, PublicKeyToken=null' (Parameter 'moduleAssembly')

Stack:

   at EPiServer.Shell.Paths.ToResource(Assembly moduleAssembly, String moduleRelativeResourcePath)
   at EPiServer.Shell.ViewComposition.IFrameComponentAttribute.CreateComponentDefinition(Type attributedType)
   at System.Linq.Enumerable.SelectEnumerableIterator`2.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at EPiServer.Shell.ViewComposition.AttributedComponentProvider.GetComponentDefinitions()
   at EPiServer.Shell.ViewComposition.ComponentManager.ListAll()
   at EPiServer.Shell.ViewComposition.DefaultViewManager..ctor(IEnumerable`1 viewProviders, IEnumerable`1 viewTransformers, IComponentManager componentManager)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at EPiServer.Shell.Modules.ModuleInitializer.RegisterServerRoutes(ShellModule shellModule, IEndpointRouteBuilder routeBuilder)
   at EPiServer.Shell.Modules.ModuleInitializer.RegisterModules(IEnumerable`1 modules, IEndpointRouteBuilder routeBuilder)
   at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.InitializeModules(IEndpointRouteBuilder routeBuilder, IEnumerable`1 modules)
   at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.MapEndpoints(IEndpointRouteBuilder endpointRouteBuilder)
   at EPiServer.Web.Routing.EndpointRouteBuilderExtensions.MapEPiServerExtensionEndpoints(IEndpointRouteBuilder defaultEndpointRouteBuilder)
   at EPiServer.Web.Routing.ContentEndpointRouteBuilderExtensions.MapContent(IEndpointRouteBuilder defaultEndpointRouteBuilder)
   at Abcde.Web.Startup.<>c.<Configure>b__4_0(IEndpointRouteBuilder endpoints) in C:\source\Abcde\Abcde.Web\Startup.cs:line 105
   at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
   at Abcde.Web.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in C:\source\Abcde\Abcde.Web\Startup.cs:line 103
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass15_0.<UseStartup>b__1(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__37.MoveNext()

Abcde.Web, 4.26.9.0 is the main dll of the website.

Any input would be appriciated!

#307724
Aug 31, 2023 7:16
Vote:
 

You probably have old shell modules in the /modules folder. You can clear that folder completely and exclude them from source control. 

#307735
Aug 31, 2023 11:20
Vote:
 

Do you have a module.config in the root of the web project, and what does that configuration look like?

#307737
Aug 31, 2023 11:23
Vote:
 

From what I can tell, there isn't any old shell module from any of the projects. The only reference I find is to 12.22.5 and that's also the module I find in my bin/debug/net6.0/moduels/_protected folder.

I had an old module.config, but it was only for some screen9-stuff (see below). Removing it did not help.

I've cleant and rebuilt between tries to make sure there is no old junk interfering.

I did get the log running and there are messages saying the modules finder can't find some folders. Just a warning so I'm not sure it's helpful.

Also some warnings regarding the geta modules that aren't setup correctly yet. I'll try to get those sorted, but again, just warnings.

Oh right, I bumped the version because apparently at some point I had run a higher version, so it was complaining that db was not going to be updated because of the version missmatch.

log.txt:

2023-08-31 13:44:13.078 +02:00 [WRN] Database connection is configured to allow MultipleActiveResultSets. Consider disable MultipleActiveResultSets for better performance.
2023-08-31 13:44:13.139 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.VisitorGroups'
2023-08-31 13:44:13.139 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.Settings'
2023-08-31 13:44:13.139 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.Admin'
2023-08-31 13:44:13.139 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/Shell'
2023-08-31 13:44:13.139 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.TinyMce'
2023-08-31 13:44:13.140 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/CMS'
2023-08-31 13:44:13.141 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.VisitorGroups'
2023-08-31 13:44:13.142 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.Settings'
2023-08-31 13:44:13.144 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.Admin'
2023-08-31 13:44:13.145 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/Shell'
2023-08-31 13:44:13.146 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.TinyMce'
2023-08-31 13:44:13.148 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/CMS'
2023-08-31 13:44:14.566 +02:00 [WRN] Failed to create an instance of scheduled job ec74d2a3-9d77-4265-b4ff-a1935e3c3110 of type Geta.Optimizely.Sitemaps.SitemapCreateJob, Geta.Optimizely.Sitemaps
System.InvalidOperationException: No service for type 'Geta.Optimizely.Sitemaps.Repositories.ISitemapRepository' has been registered.
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Geta.Optimizely.Sitemaps.SitemapCreateJob..ctor()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobFactory.Create(ScheduledJob job, IServiceProvider serviceProvider)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobScanner.GetIsStoppable(ScheduledJob newScheduledJob)
2023-08-31 13:44:14.619 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/Shell'
2023-08-31 13:44:14.620 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.TinyMce'
2023-08-31 13:44:14.620 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.VisitorGroups'
2023-08-31 13:44:14.620 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.Settings'
2023-08-31 13:44:14.619 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/EPiServer.Cms.UI.Admin'
2023-08-31 13:44:14.619 +02:00 [WRN] The modules finder couldn't find a directory at '~/EPiServer/CMS'
2023-08-31 13:44:14.649 +02:00 [WRN] Failed to create an instance of scheduled job 53c743ae-e152-497a-a7e5-7e30f4b5b321 of type Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.IndexContentUrlsJob, Geta.NotFoundHandler.Optimizely
System.InvalidOperationException: Unable to resolve service for type 'Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.ContentUrlIndexer' while attempting to activate 'Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.IndexContentUrlsJob'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobFactory.Create(ScheduledJob job, IServiceProvider serviceProvider)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobScanner.GetIsStoppable(ScheduledJob newScheduledJob)
2023-08-31 13:44:14.650 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/Shell'
2023-08-31 13:44:14.651 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.TinyMce'
2023-08-31 13:44:14.662 +02:00 [WRN] Failed to create an instance of scheduled job ec96abee-5da4-404f-a0c8-451c77ca4983 of type Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.RegisterMovedContentRedirectsJob, Geta.NotFoundHandler.Optimizely
System.InvalidOperationException: Unable to resolve service for type 'Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.IAutomaticRedirectsService' while attempting to activate 'Geta.NotFoundHandler.Optimizely.Core.AutomaticRedirects.RegisterMovedContentRedirectsJob'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobFactory.Create(ScheduledJob job, IServiceProvider serviceProvider)
   at EPiServer.Scheduler.Internal.DefaultScheduledJobScanner.GetIsStoppable(ScheduledJob newScheduledJob)
2023-08-31 13:44:14.653 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.VisitorGroups'
2023-08-31 13:44:14.655 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.Settings'
2023-08-31 13:44:14.657 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/EPiServer.Cms.UI.Admin'
2023-08-31 13:44:14.658 +02:00 [WRN] The modules finder couldn't find a directory at '/EPiServer/CMS'
2023-08-31 13:44:17.633 +02:00 [FTL] Application startup exception
System.ArgumentException: Unable to find a module by assembly 'Abcde.Web, Version=4.27.1.0, Culture=neutral, PublicKeyToken=null' (Parameter 'moduleAssembly')
   at EPiServer.Shell.Paths.ToResource(Assembly moduleAssembly, String moduleRelativeResourcePath)
   at EPiServer.Shell.ViewComposition.IFrameComponentAttribute.CreateComponentDefinition(Type attributedType)
   at System.Linq.Enumerable.SelectEnumerableIterator`2.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at EPiServer.Shell.ViewComposition.AttributedComponentProvider.GetComponentDefinitions()
   at EPiServer.Shell.ViewComposition.ComponentManager.ListAll()
   at EPiServer.Shell.ViewComposition.DefaultViewManager..ctor(IEnumerable`1 viewProviders, IEnumerable`1 viewTransformers, IComponentManager componentManager)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at EPiServer.Shell.Modules.ModuleInitializer.RegisterServerRoutes(ShellModule shellModule, IEndpointRouteBuilder routeBuilder)
   at EPiServer.Shell.Modules.ModuleInitializer.RegisterModules(IEnumerable`1 modules, IEndpointRouteBuilder routeBuilder)
   at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.InitializeModules(IEndpointRouteBuilder routeBuilder, IEnumerable`1 modules)
   at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.MapEndpoints(IEndpointRouteBuilder endpointRouteBuilder)
   at EPiServer.Web.Routing.EndpointRouteBuilderExtensions.MapEPiServerExtensionEndpoints(IEndpointRouteBuilder defaultEndpointRouteBuilder)
   at EPiServer.Web.Routing.ContentEndpointRouteBuilderExtensions.MapContent(IEndpointRouteBuilder defaultEndpointRouteBuilder)
   at Abcde.Web.Startup.<>c.<Configure>b__4_0(IEndpointRouteBuilder endpoints) in C:\source\Abcde\Abcde.Web\Startup.cs:line 106
   at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
   at Abcde.Web.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in C:\source\Abcde\Abcde.Web\Startup.cs:line 102
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass15_0.<UseStartup>b__1(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)

Old module.config:

<?xml version="1.0" encoding="utf-8"?>
<module>
  <clientResources>
    <add name="epi-cms.widgets.base" path="Styles/Screen9GlobalStyles.css" resourceType="Style" />
  </clientResources>
  <dojo>
    <paths>
      <add name="s9" path="Scripts" />
    </paths>
  </dojo>
  <clientModule initializer="s9/Screen9Initilizer" />
</module>

#307742
Aug 31, 2023 11:54
Vote:
 

I made some progress!
I was looking at the stack and looking into the code with dotPeek, wondering why it was looking for a module in my dll at all.
The clue is in the stack:
at EPiServer.Shell.ViewComposition.IFrameComponentAttribute.CreateComponentDefinition(Type attributedType)

Searching for IFrameComponent found two classes with that attribute. Don't know what they do, and don't care right now. Just comment out the attribute and move on.
Now I'm getting missing DI-stuff, but thats to be expected at this point.

#307751
Edited, Aug 31, 2023 13:55
Vote:
 

Got another interesting error after fixing my Di-issues. Thought I'd just post my findings here in case any one else will run into the same problem. Maybe this should be a blog post, but that old thing isn't up and running at the moment.

So, I got the same error as in: https://world.optimizely.com/forum/developer-forum/cms-12/thread-container/2022/5/-net-6-new-minimal-hosting-model-with-cms-12-giving-exception-at-startup/

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at EPiServer.Shell.Modules.ModuleInitializer.RegisterNlsRoute(String name, String path, ShellModule shellModuleNamedShell, ShellModule module, String clientResourcePath, IEndpointRouteBuilder routeBuilder)
at EPiServer.Shell.Modules.ModuleInitializer.RegisterClientResourceRoutes(IEnumerable`1 modules, IEndpointRouteBuilder routeBuilder)
at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.InitializeModules(IEndpointRouteBuilder routeBuilder, IEnumerable`1 modules)
at EPiServer.Shell.Routing.ShellEndpointRoutingExtension.MapEndpoints(IEndpointRouteBuilder endpointRouteBuilder)
at EPiServer.Web.Routing.EndpointRouteBuilderExtensions.MapEPiServerExtensionEndpoints(IEndpointRouteBuilder defaultEndpointRouteBuilder)
at EPiServer.Web.Routing.ContentEndpointRouteBuilderExtensions.MapContent(IEndpointRouteBuilder defaultEndpointRouteBuilder)
at Web.Startup.<>c__DisplayClass3_0.<Configure>b__0(IEndpointRouteBuilder endpoints) in C:\Dev\Experiments\Web\Startup.cs:line 311
at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
at Web.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in C:\Dev\Experiments\Web\Startup.cs:line 309
at Program.<Main>$(String[] args) in C:\Dev\Experiments\Web\Program.cs:line 19
 

But I wasn't using the minimal hosting model. in fact, I had installed a clean alloy site and made sure I had everything set up in the same way, plus some extras (Geta, Screen9, addon.settings etc).

Something was null. So very null.

So away to dotPeek we go!

private void RegisterNlsRoute(
            string name,
            string path,
            ShellModule shellModuleNamedShell,
            ShellModule module,
            string clientResourcePath,
            IEndpointRouteBuilder routeBuilder)
        {
            if (new Uri(path, UriKind.RelativeOrAbsolute).IsAbsoluteUri) return;

            string pattern = VirtualPathUtilityEx.AppendTrailingSlash(UriUtil.Combine(clientResourcePath, path).TrimStart('~', '/')) + "{**pathInfo:epi-dojo-nls}";
            RouteValueDictionary defaults = new RouteValueDictionary(new
            {
                controller = "EPiResources",
                action = "DojoResources",
                module = module,
                area = shellModuleNamedShell.Name
            });

            RouteValueDictionary dataTokens = new RouteValueDictionary(new
            {
                module = shellModuleNamedShell,
                shellModule = module
            });

            routeBuilder.MapControllerRoute(name, pattern, defaults, dataTokens: dataTokens).RequireShellAuthorization<ControllerActionEndpointConventionBuilder>(module);
        }

It looks like there are only two places that would throw null, "shellModuleNameShell.Name" or "routeBuilder.MapControllerRoute(...)".
Lets take a step back in the stack and look at the calling method:

internal void RegisterClientResourceRoutes(
            IEnumerable<ShellModule> modules,
            IEndpointRouteBuilder routeBuilder)
        {
            ShellModule shellModuleNamedShell = modules.FirstOrDefault<ShellModule>(m => m.Name == "Shell");
            VirtualPathResolver.Instance.ToAppRelative(_protectedOptions.RootPath);
            foreach (ShellModule module in modules)
            {
                string appRelative = VirtualPathResolver.Instance.ToAppRelative(module.ClientResourcePath);
                string absolute = VirtualPathResolver.Instance.ToAbsolute(module.ClientResourcePath);
                string url = VirtualPathUtilityEx.AppendTrailingSlash(appRelative.TrimStart('~', '/')) + "{folder}/{**path:epi-staticfile}";
                IEndpointConventionBuilder builder = MapStaticFiles(module.Name, url, routeBuilder);

                if (!module.IsPublic)
                {
                    builder.RequireClientShellAuthorization<IEndpointConventionBuilder>(module);
                }

                foreach (DojoPath dojoModule in module.Manifest.DojoModules)
                {
                    RegisterNlsRoute(dojoModule.Name, dojoModule.Path, shellModuleNamedShell, module, appRelative, routeBuilder);
                }

                DojoConfiguration dojo = module.Manifest.Dojo;
                if (dojo != null)
                {
                    foreach (DojoPath path in dojo.Paths)
                    {
                        RegisterNlsRoute(path.Name, path.Path, shellModuleNamedShell, module, appRelative, routeBuilder);
                    }

                    foreach (DojoPackage package in dojo.Packages)
                    {
                        RegisterNlsRoute(package.Name, package.Location, shellModuleNamedShell, module, appRelative, routeBuilder);
                    }

                    RegisterVersionAgnosticRoute(module, absolute, routeBuilder);
                }
            }
        }

ShellModuleNamedShell is loaded with modules.FirstOrDefault(...) so that could be null. But no shell module? Why?
I verified that I had the shell module in modules/_protected, yes, and same as in the allow site.
Looking at the log there was no Shellmodule 'Shell' like in the log from alloy:

[10:19:12 DBG] Found module: [ShellModule Name='Shell' RouteBasePath='EPiServer/' ResourceBasePath='/EPiServer/Shell/' ClientResourcePath='/EPiServer/Shell/12.22.5/' Assemblies=[EPiServer.Shell, EPiServer.Shell.UI, EPiServer.ApplicationModules] Controllers=undefined] <s:EPiServer.Shell.Modules.ModuleFinder>

Where does the module come from? Well if we look at alloy again, there is only one nuget reference: EPiServer.CMS.

The site I'm working on is a little bit bigger and split into multiple projects. Basically It's set up like so: Abcde.Web -> Abcde.Core -> EPiServer.CMS.

Hmm, what if I add EPiServer.CMS directly into Abcde.Web?

🎉

Site is starting!
Well, this is still an upgrade in progress, so it's still broken.

#307818
Sep 01, 2023 9:27
Vote:
 

Just to add to the discussion here

We've stumbled upon the dreadful RegisterNlsRoute error several times, and it means that a module.zip is missing from the published package.

It's never a problem for Episerver's demo site Foundation, since it has direct references to all the packages.

But as in your case, if you have indirect references to packages that carry modules, you need to make sure these modules are copied to the site project. It took us a while to figure this out, as it is not documented anywhere.

We couldn't get the errors on local machine, only when we built on our build server.

We've tried several approaches, but in the end we made it work by a custom Target in the csproj [of the site] that would deal with the copying. The tricky part was to make it run at the right time.

We started out by chaining it to run just after Build, like so:

<Target Name="CopyModulesFromOtherProject" AfterTargets="Build">
  ...
</Target>

This worked in 90% of the cases, but somtimes not - probably because of timing issues.

In the end, what made it work was to chain it right after AfterResolveReferences, like so:

<Target Name="CopyModulesFromOtherProject" AfterTargets="AfterResolveReferences">
  ...
</Target>

Hope this info is useful for anyone that is struggling with the same problem 😊

#312948
Edited, Nov 22, 2023 13:20
Vote:
 

One solution is to install packages that contains modules in the web project. These are most likely add-ons and should be installed in the web project. Installing packages that has modules in class library projects is not recommended, because then the module is copied to a modules folder in that project. Add-ons are typically split into a core and an UI package. Class library projects usually only needs the core package.

#312954
Nov 22, 2023 15:10
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.