From bcaede22f17e9be061b4cf82c58a9424c9d4d76b Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 15:18:55 +1000 Subject: [PATCH 1/9] Cleans up ext methods and where they are located and what they call to ensure dependencies are taken care of, cleans up Startup, moves routing appropriately --- .../UmbracoServiceProviderFactory.cs | 14 ++- src/Umbraco.Tests.Integration/RuntimeTests.cs | 2 +- .../Testing/UmbracoIntegrationTest.cs | 2 +- .../AspNetCoreHttpContextAccessor.cs | 16 --- .../UmbracoApplicationBuilderExtensions.cs | 111 ------------------ ...oBackOfficeApplicationBuilderExtensions.cs | 40 +++++++ .../ApplicationBuilderExtensions.cs | 111 ++++++++++++++++++ .../UmbracoWebServiceCollectionExtensions.cs | 4 + .../UmbracoRequestLoggingMiddleware.cs | 14 +-- .../Middleware/UmbracoRequestMiddleware.cs | 18 +-- src/Umbraco.Web.UI.NetCore/Startup.cs | 57 +-------- ...racoWebsiteApplicationBuilderExtensions.cs | 6 +- 12 files changed, 195 insertions(+), 200 deletions(-) delete mode 100644 src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHttpContextAccessor.cs delete mode 100644 src/Umbraco.Web.BackOffice/AspNetCore/UmbracoApplicationBuilderExtensions.cs create mode 100644 src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs rename src/Umbraco.Web.Website/{AspNetCore => Extensions}/UmbracoWebsiteApplicationBuilderExtensions.cs (66%) diff --git a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs b/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs index b8fad4828c..9efbaee7f1 100644 --- a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs +++ b/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs @@ -1,9 +1,11 @@ using LightInject; using LightInject.Microsoft.DependencyInjection; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using System; +using Umbraco.Composing; using Umbraco.Core.Composing.LightInject; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; namespace Umbraco.Core.Composing { @@ -75,6 +77,16 @@ namespace Umbraco.Core.Composing public IServiceProvider CreateServiceProvider(IServiceContainer containerBuilder) { var provider = containerBuilder.CreateServiceProvider(_services); + + // after cross wiring, configure "Current" + Current.Initialize( + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance()); + return provider; } diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 13a54206fa..69119b7984 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -15,9 +15,9 @@ using Umbraco.Tests.Common; using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; using Umbraco.Tests.Integration.Testing; -using Umbraco.Web.BackOffice.AspNetCore; using Umbraco.Web.Common.AspNetCore; using Umbraco.Extensions; +using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Tests.Integration { diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index c7f1270fc6..d479ad7213 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -17,8 +17,8 @@ using Umbraco.Core.Strings; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; -using Umbraco.Web.BackOffice.AspNetCore; using Umbraco.Extensions; +using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Tests.Integration.Testing { diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHttpContextAccessor.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHttpContextAccessor.cs deleted file mode 100644 index 696005f2fb..0000000000 --- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHttpContextAccessor.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.AspNetCore.Http; - -namespace Umbraco.Web.BackOffice.AspNetCore -{ - internal class AspNetCoreHttpContextAccessor //: IHttpContextAccessor - { - private readonly IHttpContextAccessor _httpContextAccessor; - - public AspNetCoreHttpContextAccessor(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - - public HttpContext HttpContext => _httpContextAccessor.HttpContext; - } -} diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoApplicationBuilderExtensions.cs deleted file mode 100644 index e886ccc9e5..0000000000 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoApplicationBuilderExtensions.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Serilog.Context; -using Smidge; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Hosting; -using Umbraco.Extensions; -using Umbraco.Infrastructure.Logging.Serilog.Enrichers; -using Umbraco.Web.Common.Middleware; - -namespace Umbraco.Web.BackOffice.AspNetCore -{ - public static class UmbracoApplicationBuilderExtensions - { - public static IApplicationBuilder UseUmbracoBackOffice(this IApplicationBuilder app) - { - if (app == null) throw new ArgumentNullException(nameof(app)); - - if (!app.UmbracoCanBoot()) return app; - - // TODO: start the back office - - return app; - } - - /// - /// Start Umbraco - /// - /// - /// - public static IApplicationBuilder UseUmbracoCore(this IApplicationBuilder app) - { - if (app == null) throw new ArgumentNullException(nameof(app)); - - if (app.UmbracoCanBoot()) - { - var runtime = app.ApplicationServices.GetRequiredService(); - - // Register a listener for application shutdown in order to terminate the runtime - var hostLifetime = app.ApplicationServices.GetRequiredService(); - var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime); - hostLifetime.RegisterObject(runtimeShutdown); - - // Register our global threadabort enricher for logging - var threadAbortEnricher = app.ApplicationServices.GetRequiredService(); - LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context - - // Start the runtime! - runtime.Start(); - } - else - { - // TODO: Register simple middleware to show the error like we used to in UmbracoModule? Or maybe that's part of a UseUmbracoWebsite/backoffice type thing .. probably :) - - } - - return app; - } - - /// - /// Ensures the runtime is shutdown when the application is shutting down - /// - private class CoreRuntimeShutdown : IRegisteredObject - { - public CoreRuntimeShutdown(IRuntime runtime, IApplicationShutdownRegistry hostLifetime) - { - _runtime = runtime; - _hostLifetime = hostLifetime; - } - - private bool _completed = false; - private readonly IRuntime _runtime; - private readonly IApplicationShutdownRegistry _hostLifetime; - - public void Stop(bool immediate) - { - if (!_completed) - { - _completed = true; - _runtime.Terminate(); - _hostLifetime.UnregisterObject(this); - } - - } - } - - public static IApplicationBuilder UseUmbracoRequestLogging(this IApplicationBuilder app) - { - if (app == null) throw new ArgumentNullException(nameof(app)); - - if (!app.UmbracoCanBoot()) return app; - - app.UseMiddleware(); - - return app; - } - - public static IApplicationBuilder UseUmbracoRuntimeMinification(this IApplicationBuilder app) - { - if (app == null) throw new ArgumentNullException(nameof(app)); - - if (!app.UmbracoCanBoot()) return app; - - app.UseSmidge(); - - return app; - } - } -} diff --git a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..8043e645b7 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.AspNetCore.Builder; +using SixLabors.ImageSharp.Web.DependencyInjection; +using Umbraco.Extensions; + +namespace Umbraco.Web.BackOffice.Extensions +{ + public static class UmbracoBackOfficeApplicationBuilderExtensions + { + public static IApplicationBuilder UseUmbracoBackOffice(this IApplicationBuilder app) + { + if (app == null) throw new ArgumentNullException(nameof(app)); + + if (!app.UmbracoCanBoot()) return app; + + app.UseEndpoints(endpoints => + { + // TODO: This is temporary, 'umbraco' cannot be hard coded, needs to use GetUmbracoMvcArea() + // but actually we need to route all back office stuff in a back office area like we do in v8 + + endpoints.MapControllerRoute("Backoffice", "/umbraco/{Action}", new + { + Controller = "BackOffice", + Action = "Default" + }); + }); + + app.UseUmbracoRuntimeMinification(); + + // Important we handle image manipulations before the static files, otherwise the querystring is just ignored. + // TODO: Since we are dependent on these we need to register them but what happens when we call this multiple times since we are dependent on this for UseUmbracoWebsite too? + app.UseImageSharp(); + app.UseStaticFiles(); + + return app; + } + + + } +} diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index 47cee99264..da68e4d634 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -1,8 +1,12 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; +using Serilog.Context; +using Smidge; using StackExchange.Profiling; using Umbraco.Core; +using Umbraco.Core.Hosting; +using Umbraco.Infrastructure.Logging.Serilog.Enrichers; using Umbraco.Web.Common.Middleware; namespace Umbraco.Extensions @@ -21,6 +25,59 @@ namespace Umbraco.Extensions return runtime.State.Level > RuntimeLevel.BootFailed; } + /// + /// Enables the Umbraco installer + /// + /// + /// + public static IApplicationBuilder UseUmbracoInstaller(this IApplicationBuilder app) + { + app.UseEndpoints(endpoints => + { + // TODO: Fix this routing with an area + endpoints.MapControllerRoute("Install", "/install/{controller}/{Action}", defaults: new { Area = "Install" }); + + //TODO register routing correct: Name must be like this + endpoints.MapControllerRoute("umbraco-api-UmbracoInstall-InstallApi", "/install/api/{Action}", defaults: new { Area = "Install", Controller = "InstallApi" }); + }); + + return app; + } + + /// + /// Start Umbraco + /// + /// + /// + public static IApplicationBuilder UseUmbracoCore(this IApplicationBuilder app) + { + if (app == null) throw new ArgumentNullException(nameof(app)); + + if (app.UmbracoCanBoot()) + { + var runtime = app.ApplicationServices.GetRequiredService(); + + // Register a listener for application shutdown in order to terminate the runtime + var hostLifetime = app.ApplicationServices.GetRequiredService(); + var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime); + hostLifetime.RegisterObject(runtimeShutdown); + + // Register our global threadabort enricher for logging + var threadAbortEnricher = app.ApplicationServices.GetRequiredService(); + LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context + + // Start the runtime! + runtime.Start(); + } + else + { + // TODO: Register simple middleware to show the error like we used to in UmbracoModule? Or maybe that's part of a UseUmbracoWebsite/backoffice type thing .. probably :) + + } + + return app; + } + /// /// Enables middlewares required to run Umbraco /// @@ -37,6 +94,60 @@ namespace Umbraco.Extensions app.UseMiddleware(); return app; } + + public static IApplicationBuilder UseUmbracoRequestLogging(this IApplicationBuilder app) + { + if (app == null) throw new ArgumentNullException(nameof(app)); + + if (!app.UmbracoCanBoot()) return app; + + app.UseMiddleware(); + + return app; + } + + /// + /// Enables runtime minification for Umbraco + /// + /// + /// + public static IApplicationBuilder UseUmbracoRuntimeMinification(this IApplicationBuilder app) + { + if (app == null) throw new ArgumentNullException(nameof(app)); + + if (!app.UmbracoCanBoot()) return app; + + app.UseSmidge(); + + return app; + } + + /// + /// Ensures the runtime is shutdown when the application is shutting down + /// + private class CoreRuntimeShutdown : IRegisteredObject + { + public CoreRuntimeShutdown(IRuntime runtime, IApplicationShutdownRegistry hostLifetime) + { + _runtime = runtime; + _hostLifetime = hostLifetime; + } + + private bool _completed = false; + private readonly IRuntime _runtime; + private readonly IApplicationShutdownRegistry _hostLifetime; + + public void Stop(bool immediate) + { + if (!_completed) + { + _completed = true; + _runtime.Terminate(); + _hostLifetime.UnregisterObject(this); + } + + } + } } } diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs index fb7d379ae5..559730bdc3 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs @@ -20,6 +20,7 @@ using Smidge.Nuglify; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Web.Common.ApplicationModels; +using Umbraco.Web.Common.Middleware; using Umbraco.Web.Common.ModelBinding; namespace Umbraco.Extensions @@ -33,6 +34,9 @@ namespace Umbraco.Extensions /// public static IServiceCollection AddUmbracoWebComponents(this IServiceCollection services) { + services.AddTransient(); + services.AddTransient(); + services.TryAddSingleton(); services.ConfigureOptions(); services.TryAddEnumerable(ServiceDescriptor.Transient()); diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs index b1d2d01f9d..803eb95d62 100644 --- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs +++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs @@ -8,30 +8,28 @@ using Umbraco.Core.Logging.Serilog.Enrichers; namespace Umbraco.Web.Common.Middleware { - public class UmbracoRequestLoggingMiddleware + public class UmbracoRequestLoggingMiddleware : IMiddleware { - readonly RequestDelegate _next; private readonly HttpSessionIdEnricher _sessionIdEnricher; private readonly HttpRequestNumberEnricher _requestNumberEnricher; private readonly HttpRequestIdEnricher _requestIdEnricher; - public UmbracoRequestLoggingMiddleware(RequestDelegate next, + public UmbracoRequestLoggingMiddleware( HttpSessionIdEnricher sessionIdEnricher, HttpRequestNumberEnricher requestNumberEnricher, HttpRequestIdEnricher requestIdEnricher) { - _next = next; _sessionIdEnricher = sessionIdEnricher; _requestNumberEnricher = requestNumberEnricher; _requestIdEnricher = requestIdEnricher; } - public async Task Invoke(HttpContext httpContext) + public async Task InvokeAsync(HttpContext context, RequestDelegate next) { // do not process if client-side request - if (new Uri(httpContext.Request.GetEncodedUrl(), UriKind.RelativeOrAbsolute).IsClientSideRequest()) + if (new Uri(context.Request.GetEncodedUrl(), UriKind.RelativeOrAbsolute).IsClientSideRequest()) { - await _next(httpContext); + await next(context); return; } @@ -42,7 +40,7 @@ namespace Umbraco.Web.Common.Middleware using (LogContext.Push(_requestNumberEnricher)) using (LogContext.Push(_requestIdEnricher)) { - await _next(httpContext); + await next(context); } } } diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs index 85cf6607cc..e1662e834f 100644 --- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs +++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs @@ -5,46 +5,46 @@ using Microsoft.AspNetCore.Http.Extensions; using Umbraco.Web.Common.Lifetime; using Umbraco.Core; using Umbraco.Core.Logging; +using System.Threading; namespace Umbraco.Web.Common.Middleware { + /// /// Manages Umbraco request objects and their lifetime /// - public class UmbracoRequestMiddleware + public class UmbracoRequestMiddleware : IMiddleware { - private readonly RequestDelegate _next; private readonly ILogger _logger; private readonly IUmbracoRequestLifetimeManager _umbracoRequestLifetimeManager; private readonly IUmbracoContextFactory _umbracoContextFactory; - public UmbracoRequestMiddleware(RequestDelegate next, + public UmbracoRequestMiddleware( ILogger logger, IUmbracoRequestLifetimeManager umbracoRequestLifetimeManager, IUmbracoContextFactory umbracoContextFactory) { - _next = next; _logger = logger; _umbracoRequestLifetimeManager = umbracoRequestLifetimeManager; _umbracoContextFactory = umbracoContextFactory; } - public async Task InvokeAsync(HttpContext context) + public async Task InvokeAsync(HttpContext context, RequestDelegate next) { // do not process if client-side request if (new Uri(context.Request.GetEncodedUrl(), UriKind.RelativeOrAbsolute).IsClientSideRequest()) { - await _next(context); + await next(context); return; } var umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext(); - + try { try - { + { _umbracoRequestLifetimeManager.InitRequest(context); } catch (Exception ex) @@ -53,7 +53,7 @@ namespace Umbraco.Web.Common.Middleware _logger.Error(ex); } - await _next(context); + await next(context); _umbracoRequestLifetimeManager.EndRequest(context); } diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index bd23ef4229..1ad434fdd7 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -1,30 +1,12 @@ using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Data.SqlClient; -using System.IO; -using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json.Serialization; -using Umbraco.Composing; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.SqlSyntax; -using Umbraco.Web.BackOffice.AspNetCore; using Umbraco.Extensions; -using Umbraco.Web.Common.Filters; -using Umbraco.Web.Website.AspNetCore; -using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment; - +using Umbraco.Web.Website.Extensions; +using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Web.UI.BackOffice { @@ -62,24 +44,11 @@ namespace Umbraco.Web.UI.BackOffice { options.ShouldProfile = request => false; // WebProfiler determine and start profiling. We should not use the MiniProfilerMiddleware to also profile }); - - //Finally initialize Current - // TODO: This should be moved to the UmbracoServiceProviderFactory when the container is cross-wired and then don't use the overload above to `out var factory` - Current.Initialize( - factory.GetInstance (), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance() - ); - } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { - //app.UseMiniProfiler(); if (_env.IsDevelopment()) { @@ -89,29 +58,15 @@ namespace Umbraco.Web.UI.BackOffice app.UseStatusCodePages(); app.UseRouting(); - - app.UseUmbracoRouting(); app.UseUmbracoCore(); + app.UseUmbracoRouting(); app.UseUmbracoRequestLogging(); app.UseUmbracoWebsite(); - app.UseUmbracoBackOffice(); - app.UseUmbracoRuntimeMinification(); - + app.UseUmbracoBackOffice(); + app.UseUmbracoInstaller(); app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute("Backoffice", "/umbraco/{Action}", new - { - Controller = "BackOffice", - Action = "Default" - }); - - // TODO: Fix this routing with an area - endpoints.MapControllerRoute("Install", "/install/{controller}/{Action}", defaults:new { Area = "Install"}); - - //TODO register routing correct: Name must be like this - endpoints.MapControllerRoute("umbraco-api-UmbracoInstall-InstallApi", "/install/api/{Action}", defaults:new { Area = "Install", Controller = "InstallApi"}); - + { endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action=Index}/{id?}"); diff --git a/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteApplicationBuilderExtensions.cs b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs similarity index 66% rename from src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteApplicationBuilderExtensions.cs rename to src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs index 2fc8f70f2e..f6a54b8b0a 100644 --- a/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs @@ -4,10 +4,11 @@ using Microsoft.Extensions.DependencyInjection; using SixLabors.ImageSharp.Web.DependencyInjection; using Umbraco.Core; using Umbraco.Extensions; +using Umbraco.Web.Common.Middleware; -namespace Umbraco.Web.Website.AspNetCore +namespace Umbraco.Web.Website.Extensions { - public static class UmbracoBackOfficeApplicationBuilderExtensions + public static class UmbracoWebsiteApplicationBuilderExtensions { public static IApplicationBuilder UseUmbracoWebsite(this IApplicationBuilder app) { @@ -16,6 +17,7 @@ namespace Umbraco.Web.Website.AspNetCore if (!app.UmbracoCanBoot()) return app; // Important we handle image manipulations before the static files, otherwise the querystring is just ignored. + // TODO: Since we are dependent on these we need to register them but what happens when we call this multiple times since we are dependent on this for UseUmbracoBackOffice too? app.UseImageSharp(); app.UseStaticFiles(); From 1f25e28e08c441e527e22205517afa81fda235fc Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 15:44:14 +1000 Subject: [PATCH 2/9] Move install ext methods to it's own class, adds catch all redirect when we need to install --- ...oBackOfficeApplicationBuilderExtensions.cs | 4 ++ .../ApplicationBuilderExtensions.cs | 21 +----- ...racoInstallApplicationBuilderExtensions.cs | 70 +++++++++++++++++++ 3 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs diff --git a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs index 8043e645b7..ee22b5beed 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs @@ -18,6 +18,10 @@ namespace Umbraco.Web.BackOffice.Extensions // TODO: This is temporary, 'umbraco' cannot be hard coded, needs to use GetUmbracoMvcArea() // but actually we need to route all back office stuff in a back office area like we do in v8 + // TODO: We will also need to detect runtime state here and redirect to the installer, + // Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install + // when required, example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/ + endpoints.MapControllerRoute("Backoffice", "/umbraco/{Action}", new { Controller = "BackOffice", diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index da68e4d634..228f133ab0 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Serilog.Context; @@ -11,6 +12,7 @@ using Umbraco.Web.Common.Middleware; namespace Umbraco.Extensions { + public static class ApplicationBuilderExtensions { /// @@ -25,24 +27,7 @@ namespace Umbraco.Extensions return runtime.State.Level > RuntimeLevel.BootFailed; } - /// - /// Enables the Umbraco installer - /// - /// - /// - public static IApplicationBuilder UseUmbracoInstaller(this IApplicationBuilder app) - { - app.UseEndpoints(endpoints => - { - // TODO: Fix this routing with an area - endpoints.MapControllerRoute("Install", "/install/{controller}/{Action}", defaults: new { Area = "Install" }); - - //TODO register routing correct: Name must be like this - endpoints.MapControllerRoute("umbraco-api-UmbracoInstall-InstallApi", "/install/api/{Action}", defaults: new { Area = "Install", Controller = "InstallApi" }); - }); - - return app; - } + /// /// Start Umbraco diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..b23519f389 --- /dev/null +++ b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs @@ -0,0 +1,70 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Web; + +namespace Umbraco.Extensions +{ + public static class UmbracoInstallApplicationBuilderExtensions + { + /// + /// Enables the Umbraco installer + /// + /// + /// + public static IApplicationBuilder UseUmbracoInstaller(this IApplicationBuilder app) + { + app.UseEndpoints(endpoints => + { + var runtime = app.ApplicationServices.GetRequiredService(); + var logger = app.ApplicationServices.GetRequiredService(); + var uriUtility = app.ApplicationServices.GetRequiredService(); + switch (runtime.Level) + { + case RuntimeLevel.Install: + case RuntimeLevel.Upgrade: + + // TODO: Fix this routing with an area + endpoints.MapControllerRoute("Install", "/install/{controller}/{Action}", defaults: new { Area = "Install" }); + + // TODO register routing correct: Name must be like this + endpoints.MapControllerRoute("umbraco-api-UmbracoInstall-InstallApi", "/install/api/{Action}", defaults: new { Area = "Install", Controller = "InstallApi" }); + + // TODO: Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install, + // example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/ + + // register catch all because if we are in install/upgrade mode then we'll catch everything and redirect + endpoints.MapGet("{*url}", context => + { + var uri = context.Request.GetEncodedUrl(); + // redirect to install + ReportRuntime(logger, runtime.Level, "Umbraco must install or upgrade."); + var installPath = uriUtility.ToAbsolute(Constants.SystemDirectories.Install); + var installUrl = $"{installPath}/?redir=true&url={uri}"; + context.Response.Redirect(installUrl, true); + return Task.CompletedTask; + }); + + break; + } + }); + + return app; + } + + private static bool _reported; + private static RuntimeLevel _reportedLevel; + + private static void ReportRuntime(ILogger logger, RuntimeLevel level, string message) + { + if (_reported && _reportedLevel == level) return; + _reported = true; + _reportedLevel = level; + logger.Warn(typeof(UmbracoInstallApplicationBuilderExtensions), message); + } + } + +} From 8a7bc5d3d25b6abb2f142aa7deddef87a6adef1e Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 15:45:59 +1000 Subject: [PATCH 3/9] Removes null writer --- .../UmbracoContext/UmbracoContextFactory.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs index 89751bfa08..ac4b61909c 100644 --- a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs +++ b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs @@ -99,10 +99,5 @@ namespace Umbraco.Web return new UmbracoContextReference(umbracoContext, true, _umbracoContextAccessor); } - // dummy TextWriter that does not write - private class NullWriter : TextWriter - { - public override Encoding Encoding => Encoding.UTF8; - } } } From f427059d41b0deaf2e4279bc22e3b12b00f07e53 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 17:10:02 +1000 Subject: [PATCH 4/9] Fixes routing for installer to use an area, fixes URL generation --- src/Umbraco.Core/Constants-Web.cs | 5 +++++ .../Extensions/IUrlHelperExtensions.cs | 13 +++++------- ...racoInstallApplicationBuilderExtensions.cs | 20 +++++++++++++------ .../Install/InstallApiController.cs | 2 +- .../Install/InstallController.cs | 9 +++------ .../Views/Install/Index.cshtml | 0 src/Umbraco.Web.UI.NetCore/HomeController.cs | 19 ------------------ .../Umbraco.Web.UI.NetCore.csproj | 3 ++- 8 files changed, 30 insertions(+), 41 deletions(-) rename src/Umbraco.Web.UI.NetCore/{ => Areas/UmbracoInstall}/Views/Install/Index.cshtml (100%) delete mode 100644 src/Umbraco.Web.UI.NetCore/HomeController.cs diff --git a/src/Umbraco.Core/Constants-Web.cs b/src/Umbraco.Core/Constants-Web.cs index 5602b99e2d..96f45cd1ba 100644 --- a/src/Umbraco.Core/Constants-Web.cs +++ b/src/Umbraco.Core/Constants-Web.cs @@ -49,6 +49,11 @@ /// The default authentication type used for remembering that 2FA is not needed on next login /// public const string TwoFactorRememberBrowserCookie = "TwoFactorRememberBrowser"; + + public static class Mvc + { + public const string InstallArea = "UmbracoInstall"; + } } } } diff --git a/src/Umbraco.Web.Common/Extensions/IUrlHelperExtensions.cs b/src/Umbraco.Web.Common/Extensions/IUrlHelperExtensions.cs index 6b35563ae1..c53e13f3b9 100644 --- a/src/Umbraco.Web.Common/Extensions/IUrlHelperExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/IUrlHelperExtensions.cs @@ -6,6 +6,7 @@ using Umbraco.Core; using Umbraco.Web.Common.Controllers; using Umbraco.Extensions; using Umbraco.Web.WebApi; +using Microsoft.AspNetCore.Mvc.Routing; namespace Umbraco.Extensions { @@ -101,30 +102,26 @@ namespace Umbraco.Extensions if (controllerName == null) throw new ArgumentNullException(nameof(controllerName)); if (string.IsNullOrWhiteSpace(controllerName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(controllerName)); - string routeName; if (area.IsNullOrWhiteSpace()) { - routeName = string.Format("umbraco-{0}-{1}", "api", controllerName); if (id == null) { - - return url.RouteUrl(routeName, new { controller = controllerName, action = actionName, httproute = "" }); + return url.Action(actionName, controllerName); } else { - return url.RouteUrl(routeName, new { controller = controllerName, action = actionName, id = id, httproute = "" }); + return url.Action(actionName, controllerName, new { id = id }); } } else { - routeName = string.Format("umbraco-{0}-{1}-{2}", "api", area, controllerName); if (id == null) { - return url.RouteUrl(routeName, new { controller = controllerName, action = actionName, httproute = "" }); + return url.Action(actionName, controllerName, new { area = area }); } else { - return url.RouteUrl(routeName, new { controller = controllerName, action = actionName, id = id, httproute = "" }); + return url.Action(actionName, controllerName, new { area = area, id = id }); } } } diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs index b23519f389..fcc8cc8e30 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs @@ -27,11 +27,19 @@ namespace Umbraco.Extensions case RuntimeLevel.Install: case RuntimeLevel.Upgrade: - // TODO: Fix this routing with an area - endpoints.MapControllerRoute("Install", "/install/{controller}/{Action}", defaults: new { Area = "Install" }); + var installPath = uriUtility.ToAbsolute(Constants.SystemDirectories.Install).EnsureEndsWith('/'); - // TODO register routing correct: Name must be like this - endpoints.MapControllerRoute("umbraco-api-UmbracoInstall-InstallApi", "/install/api/{Action}", defaults: new { Area = "Install", Controller = "InstallApi" }); + endpoints.MapAreaControllerRoute( + "umbraco-install-api", + Umbraco.Core.Constants.Web.Mvc.InstallArea, + $"{installPath}api/{{Action}}", + new { controller = "InstallApi" }); + + endpoints.MapAreaControllerRoute( + "umbraco-install", + Umbraco.Core.Constants.Web.Mvc.InstallArea, + $"{installPath}{{controller}}/{{Action}}", + new { controller = "Install", action = "Index" }); // TODO: Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install, // example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/ @@ -42,8 +50,8 @@ namespace Umbraco.Extensions var uri = context.Request.GetEncodedUrl(); // redirect to install ReportRuntime(logger, runtime.Level, "Umbraco must install or upgrade."); - var installPath = uriUtility.ToAbsolute(Constants.SystemDirectories.Install); - var installUrl = $"{installPath}/?redir=true&url={uri}"; + + var installUrl = $"{installPath}?redir=true&url={uri}"; context.Response.Redirect(installUrl, true); return Task.CompletedTask; }); diff --git a/src/Umbraco.Web.Common/Install/InstallApiController.cs b/src/Umbraco.Web.Common/Install/InstallApiController.cs index ca3596e93c..2d22de730b 100644 --- a/src/Umbraco.Web.Common/Install/InstallApiController.cs +++ b/src/Umbraco.Web.Common/Install/InstallApiController.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web.Common.Install [TypeFilter(typeof(HttpResponseExceptionFilter))] [TypeFilter(typeof(AngularJsonOnlyConfigurationAttribute))] [HttpInstallAuthorize] - [Area("Install")] + [Area(Umbraco.Core.Constants.Web.Mvc.InstallArea)] public class InstallApiController : ControllerBase { private readonly DatabaseBuilder _databaseBuilder; diff --git a/src/Umbraco.Web.Common/Install/InstallController.cs b/src/Umbraco.Web.Common/Install/InstallController.cs index 07f0376697..a5e035b4d0 100644 --- a/src/Umbraco.Web.Common/Install/InstallController.cs +++ b/src/Umbraco.Web.Common/Install/InstallController.cs @@ -14,12 +14,10 @@ namespace Umbraco.Web.Common.Install { /// - /// The MVC Installation controller + /// The Installation controller /// - /// - /// NOTE: All views must have their full paths as we do not have a custom view engine for the installation views! - /// [InstallAuthorize] + [Area(Umbraco.Core.Constants.Web.Mvc.InstallArea)] public class InstallController : Controller { private readonly IUmbracoContextAccessor _umbracoContextAccessor; @@ -72,7 +70,7 @@ namespace Umbraco.Web.Common.Install } // gen the install base urlAddUmbracoCore - ViewData.SetInstallApiBaseUrl(Url.GetUmbracoApiService("GetSetup", "InstallApi", "UmbracoInstall").TrimEnd("GetSetup")); + ViewData.SetInstallApiBaseUrl(Url.GetUmbracoApiService("GetSetup", "InstallApi", Umbraco.Core.Constants.Web.Mvc.InstallArea).TrimEnd("GetSetup")); // get the base umbraco folder ViewData.SetUmbracoBaseFolder(_hostingEnvironment.ToAbsolute(_globalSettings.UmbracoPath)); @@ -81,7 +79,6 @@ namespace Umbraco.Web.Common.Install await _installHelper.InstallStatus(false, ""); - // always ensure full path (see NOTE in the class remarks) return View(); } } diff --git a/src/Umbraco.Web.UI.NetCore/Views/Install/Index.cshtml b/src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml similarity index 100% rename from src/Umbraco.Web.UI.NetCore/Views/Install/Index.cshtml rename to src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml diff --git a/src/Umbraco.Web.UI.NetCore/HomeController.cs b/src/Umbraco.Web.UI.NetCore/HomeController.cs deleted file mode 100644 index 15d6d055d2..0000000000 --- a/src/Umbraco.Web.UI.NetCore/HomeController.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 - -namespace Umbraco.Web.UI.BackOffice -{ - public class HomeController : Controller - { - // GET: // - public IActionResult Index() - { - return View(); - } - } -} diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index dbb9872dc1..966cb9c86e 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -13,6 +13,7 @@ + @@ -40,7 +41,7 @@ - + true PreserveNewest From a34d94845c2f8c734ebbb3e9fcbd986d928876e9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 17:14:39 +1000 Subject: [PATCH 5/9] Fixes tests --- .../UmbracoServiceProviderFactory.cs | 25 ++++++++++++------- .../ContainerTests.cs | 2 +- src/Umbraco.Tests.Integration/RuntimeTests.cs | 2 +- .../Testing/UmbracoIntegrationTest.cs | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs b/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs index 9efbaee7f1..5931d73365 100644 --- a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs +++ b/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs @@ -14,9 +14,10 @@ namespace Umbraco.Core.Composing /// public class UmbracoServiceProviderFactory : IServiceProviderFactory { - public UmbracoServiceProviderFactory(ServiceContainer container) + public UmbracoServiceProviderFactory(ServiceContainer container, bool initializeCurrent) { _container = new LightInjectContainer(container); + _initializeCurrent = initializeCurrent; } /// @@ -37,6 +38,7 @@ namespace Umbraco.Core.Composing var container = CreateServiceContainer(); UmbracoContainer = _container = new LightInjectContainer(container); IsActive = true; + _initializeCurrent = true; } // see here for orig lightinject version https://github.com/seesharper/LightInject.Microsoft.DependencyInjection/blob/412566e3f70625e6b96471db5e1f7cd9e3e1eb18/src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs#L263 @@ -45,6 +47,7 @@ namespace Umbraco.Core.Composing IServiceCollection _services; readonly LightInjectContainer _container; + private readonly bool _initializeCurrent; internal LightInjectContainer GetContainer() => _container; @@ -78,14 +81,18 @@ namespace Umbraco.Core.Composing { var provider = containerBuilder.CreateServiceProvider(_services); - // after cross wiring, configure "Current" - Current.Initialize( - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance()); + if (_initializeCurrent) + { + // after cross wiring, configure "Current" + Current.Initialize( + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance(), + _container.GetInstance()); + } + return provider; } diff --git a/src/Umbraco.Tests.Integration/ContainerTests.cs b/src/Umbraco.Tests.Integration/ContainerTests.cs index 34a32a38a8..2098b7241e 100644 --- a/src/Umbraco.Tests.Integration/ContainerTests.cs +++ b/src/Umbraco.Tests.Integration/ContainerTests.cs @@ -31,7 +31,7 @@ namespace Umbraco.Tests.Integration // LightInject / Umbraco var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - var serviceProviderFactory = new UmbracoServiceProviderFactory(container); + var serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); var umbracoContainer = serviceProviderFactory.GetContainer(); serviceProviderFactory.CreateBuilder(services); // called during Host Builder, needed to capture services diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 69119b7984..4c55cad373 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -47,7 +47,7 @@ namespace Umbraco.Tests.Integration { // LightInject / Umbraco var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - var serviceProviderFactory = new UmbracoServiceProviderFactory(container); + var serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); var umbracoContainer = serviceProviderFactory.GetContainer(); // Special case since we are not using the Generic Host, we need to manually add an AspNetCore service to the container diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index d479ad7213..5d7056f4d0 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -35,7 +35,7 @@ namespace Umbraco.Tests.Integration.Testing public static LightInjectContainer GetUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory) { var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - serviceProviderFactory = new UmbracoServiceProviderFactory(container); + serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); var umbracoContainer = serviceProviderFactory.GetContainer(); return umbracoContainer; } From 1607045347da638461d61ac23e72a576a6c254bd Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 17:16:42 +1000 Subject: [PATCH 6/9] fix namespace --- .../UmbracoBackOfficeApplicationBuilderExtensions.cs | 2 +- src/Umbraco.Web.Common/Extensions/ViewDataExtensions.cs | 2 +- .../UmbracoWebsiteApplicationBuilderExtensions.cs | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs index ee22b5beed..d1cec6ea3d 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeApplicationBuilderExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Builder; using SixLabors.ImageSharp.Web.DependencyInjection; using Umbraco.Extensions; -namespace Umbraco.Web.BackOffice.Extensions +namespace Umbraco.Extensions { public static class UmbracoBackOfficeApplicationBuilderExtensions { diff --git a/src/Umbraco.Web.Common/Extensions/ViewDataExtensions.cs b/src/Umbraco.Web.Common/Extensions/ViewDataExtensions.cs index a76393cc22..0ec311a51b 100644 --- a/src/Umbraco.Web.Common/Extensions/ViewDataExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ViewDataExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc.ViewFeatures; using Semver; -namespace Umbraco.Web +namespace Umbraco.Extensions { public static class ViewDataExtensions { diff --git a/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs index f6a54b8b0a..3c6de4b88a 100644 --- a/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs @@ -1,12 +1,8 @@ using System; using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; using SixLabors.ImageSharp.Web.DependencyInjection; -using Umbraco.Core; -using Umbraco.Extensions; -using Umbraco.Web.Common.Middleware; -namespace Umbraco.Web.Website.Extensions +namespace Umbraco.Extensions { public static class UmbracoWebsiteApplicationBuilderExtensions { From 42c347dc21bfa6eaef87bcf470e3ffc7c74dd203 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 17:19:19 +1000 Subject: [PATCH 7/9] doh fix build --- src/Umbraco.Tests.Integration/RuntimeTests.cs | 1 - src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs | 1 - src/Umbraco.Web.UI.NetCore/Startup.cs | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 4c55cad373..bd7684fcae 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -17,7 +17,6 @@ using Umbraco.Tests.Integration.Implementations; using Umbraco.Tests.Integration.Testing; using Umbraco.Web.Common.AspNetCore; using Umbraco.Extensions; -using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Tests.Integration { diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 5d7056f4d0..a38e002810 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -18,7 +18,6 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; using Umbraco.Extensions; -using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Tests.Integration.Testing { diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 1ad434fdd7..3a86978e17 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -5,8 +5,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Umbraco.Extensions; -using Umbraco.Web.Website.Extensions; -using Umbraco.Web.BackOffice.Extensions; namespace Umbraco.Web.UI.BackOffice { From 54769e2416d5992f8831aedee43506100fa2d2f3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 May 2020 17:25:30 +1000 Subject: [PATCH 8/9] doh fix build --- .../Areas/UmbracoInstall/Views/Install/Index.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml b/src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml index 8ebd135ff3..227b7d9480 100644 --- a/src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml +++ b/src/Umbraco.Web.UI.NetCore/Areas/UmbracoInstall/Views/Install/Index.cshtml @@ -1,4 +1,4 @@ -@using Umbraco.Web +@using Umbraco.Extensions @using Umbraco.Composing @{ Layout = null; From cfcdcae64a7984c94a28717ab3afa4c01df26e92 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 May 2020 10:51:59 +0200 Subject: [PATCH 9/9] Cleanup and fixed issue with permanent redirect --- src/Umbraco.Core/UriExtensions.cs | 2 +- .../Extensions/UmbracoInstallApplicationBuilderExtensions.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs index 00cdb8fe48..9da4db110c 100644 --- a/src/Umbraco.Core/UriExtensions.cs +++ b/src/Umbraco.Core/UriExtensions.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core .TrimStart("/"); //check if this is in the umbraco back office - return afterAuthority.InvariantStartsWith(hostingEnvironment.ToAbsolute("~/install").TrimStart("/")); + return afterAuthority.InvariantStartsWith(hostingEnvironment.ToAbsolute(Constants.SystemDirectories.Install).TrimStart("/")); } /// diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs index fcc8cc8e30..1173015865 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoInstallApplicationBuilderExtensions.cs @@ -50,9 +50,9 @@ namespace Umbraco.Extensions var uri = context.Request.GetEncodedUrl(); // redirect to install ReportRuntime(logger, runtime.Level, "Umbraco must install or upgrade."); - + var installUrl = $"{installPath}?redir=true&url={uri}"; - context.Response.Redirect(installUrl, true); + context.Response.Redirect(installUrl, false); return Task.CompletedTask; });