diff --git a/src/OrchardCore/OrchardCore.Mvc.Core/ShellViewFeatureProvider.cs b/src/OrchardCore/OrchardCore.Mvc.Core/ShellViewFeatureProvider.cs index 631f9dc10c1..39e8f1eec32 100644 --- a/src/OrchardCore/OrchardCore.Mvc.Core/ShellViewFeatureProvider.cs +++ b/src/OrchardCore/OrchardCore.Mvc.Core/ShellViewFeatureProvider.cs @@ -69,19 +69,38 @@ public void PopulateFeature(IEnumerable parts, ViewsFeature fea { var assembly = Assembly.LoadFile(precompiledAssemblyPath); + var applicationPart = new ApplicationPart[] { new CompiledRazorAssemblyPart(assembly) }; + foreach (var provider in mvcFeatureProviders) { - provider.PopulateFeature(new ApplicationPart[] { new CompiledRazorAssemblyPart(assembly) }, moduleFeature); + provider.PopulateFeature(applicationPart, moduleFeature); } // Razor views are precompiled in the context of their modules, but at runtime // their paths need to be relative to the virtual "Areas/{ModuleId}" folders. + // Note: For the app's module this folder is "Areas/{env.ApplicationName}". foreach (var descriptor in moduleFeature.ViewDescriptors) { descriptor.RelativePath = '/' + module.SubPath + descriptor.RelativePath; feature.ViewDescriptors.Add(descriptor); } + // For the app's module we still allow to explicitly specify view paths relative to the app content root. + // So for the application's module we re-apply the feature providers without updating the relative paths. + // Note: This is only needed in prod mode if app's views are precompiled and views files no longer exist. + if (module.Name == _hostingEnvironment.ApplicationName) + { + foreach (var provider in mvcFeatureProviders) + { + provider.PopulateFeature(applicationPart, moduleFeature); + } + + foreach (var descriptor in moduleFeature.ViewDescriptors) + { + feature.ViewDescriptors.Add(descriptor); + } + } + moduleFeature.ViewDescriptors.Clear(); } catch (FileLoadException)