diff --git a/src/Umbraco.Configuration/Models/HostingSettings.cs b/src/Umbraco.Configuration/Models/HostingSettings.cs
index 4a156cee6a..7cfc08d2d4 100644
--- a/src/Umbraco.Configuration/Models/HostingSettings.cs
+++ b/src/Umbraco.Configuration/Models/HostingSettings.cs
@@ -22,6 +22,6 @@ namespace Umbraco.Configuration.Models
/// Gets a value indicating whether umbraco is running in [debug mode].
///
/// true if [debug mode]; otherwise, false.
- public bool DebugMode => _configuration.GetValue(Prefix+":Debug", false);
+ public bool DebugMode => _configuration.GetValue(Prefix+"Debug", false);
}
}
diff --git a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
index f7c81d6d7e..5ff83bdfd7 100644
--- a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
+++ b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
@@ -23,6 +23,9 @@ namespace Umbraco.Core.Composing
"Umbraco.PublishedCache.NuCache",
"Umbraco.ModelsBuilder.Embedded",
"Umbraco.Examine.Lucene",
+ "Umbraco.Web.Common",
+ "Umbraco.Web.BackOffice",
+ "Umbraco.Web.Website",
};
public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly)
diff --git a/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs b/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs
index 3e5361a1c1..a032720d46 100644
--- a/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs
+++ b/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Umbraco.Net
{
// TODO: This shouldn't be in this namespace?
@@ -11,5 +13,13 @@ namespace Umbraco.Net
/// Terminates the current application. The application restarts the next time a request is received for it.
///
void Restart();
+
+ event EventHandler ApplicationInit;
+ }
+
+
+ public interface IUmbracoApplicationLifetimeManager
+ {
+ void InvokeApplicationInit();
}
}
diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs
index 4321aefd7f..e7be0b6500 100644
--- a/src/Umbraco.Core/UriExtensions.cs
+++ b/src/Umbraco.Core/UriExtensions.cs
@@ -146,7 +146,7 @@ namespace Umbraco.Core
///
///
///
- internal static bool IsClientSideRequest(this Uri url)
+ public static bool IsClientSideRequest(this Uri url)
{
try
{
diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
index 4a986fa35a..f10586b94b 100644
--- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
+++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
@@ -16,6 +16,7 @@ using Umbraco.Core.Runtime;
using Umbraco.Tests.Common;
using Umbraco.Web.BackOffice;
using Umbraco.Web.BackOffice.AspNetCore;
+using Umbraco.Web.Common.AspNetCore;
using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment;
namespace Umbraco.Tests.Integration.Implementations
diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs
index 491b7e5480..652aad8928 100644
--- a/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs
+++ b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs
@@ -1,11 +1,11 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Umbraco.Core.Configuration;
-using Umbraco.Web.BackOffice.AspNetCore;
+using Umbraco.Web.Common.AspNetCore;
namespace Umbraco.Tests.Integration.Implementations
{
-
+
public class TestHostingEnvironment : AspNetCoreHostingEnvironment, Umbraco.Core.Hosting.IHostingEnvironment
{
public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) : base(hostingSettings, webHostEnvironment, httpContextAccessor)
diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs
index 210f767de1..2974a01669 100644
--- a/src/Umbraco.Tests.Integration/RuntimeTests.cs
+++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs
@@ -1,10 +1,7 @@
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Moq;
using NUnit.Framework;
-using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Umbraco.Core;
@@ -16,6 +13,7 @@ using Umbraco.Tests.Integration.Extensions;
using Umbraco.Tests.Integration.Implementations;
using Umbraco.Tests.Integration.Testing;
using Umbraco.Web.BackOffice.AspNetCore;
+using Umbraco.Web.Common.Extensions;
namespace Umbraco.Tests.Integration
{
@@ -46,11 +44,11 @@ namespace Umbraco.Tests.Integration
// LightInject / Umbraco
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
var serviceProviderFactory = new UmbracoServiceProviderFactory(container);
- var umbracoContainer = serviceProviderFactory.GetContainer();
+ 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
umbracoContainer.Register(x => Mock.Of());
-
+
var testHelper = new TestHelper();
// Create the core runtime
@@ -64,7 +62,7 @@ namespace Umbraco.Tests.Integration
Assert.IsTrue(coreRuntime.MainDom.IsMainDom);
Assert.IsNull(coreRuntime.State.BootFailedException);
- Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level);
+ Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level);
Assert.IsTrue(MyComposer.IsComposed);
Assert.IsFalse(MyComponent.IsInit);
Assert.IsFalse(MyComponent.IsTerminated);
@@ -82,7 +80,7 @@ namespace Umbraco.Tests.Integration
}
///
- /// Calling AddUmbracoCore to configure the container
+ /// Calling AddUmbracoCore to configure the container
///
[Test]
public async Task AddUmbracoCore()
@@ -209,5 +207,5 @@ namespace Umbraco.Tests.Integration
}
}
-
+
}
diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs
index 3d94e52860..43504e908a 100644
--- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs
+++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Data.Common;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
@@ -20,8 +19,8 @@ using Umbraco.Core.Strings;
using Umbraco.Tests.Common.Builders;
using Umbraco.Tests.Integration.Extensions;
using Umbraco.Tests.Integration.Implementations;
-using Umbraco.Tests.Testing;
using Umbraco.Web.BackOffice.AspNetCore;
+using Umbraco.Web.Common.Extensions;
namespace Umbraco.Tests.Integration.Testing
{
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
index 320db33568..59b7de4cf4 100644
--- a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
+++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
@@ -4,6 +4,7 @@
Exe
netcoreapp3.1
false
+ 8
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index bb1a907843..3bfc25cf50 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -99,7 +99,7 @@
-
+
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs
deleted file mode 100644
index fc38e429a0..0000000000
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Umbraco.Core;
-using Umbraco.Core.Composing;
-using Umbraco.Core.Hosting;
-using Umbraco.Net;
-using Umbraco.Core.Runtime;
-
-namespace Umbraco.Web.BackOffice.AspNetCore
-{
- ///
- /// Adds/replaces AspNetCore specific services
- ///
- [ComposeBefore(typeof(ICoreComposer))]
- [ComposeAfter(typeof(CoreInitialComposer))]
- public class AspNetCoreComposer : IComposer
- {
- public void Compose(Composition composition)
- {
- // AspNetCore specific services
- composition.RegisterUnique();
-
- // Our own netcore implementations
- composition.RegisterUnique();
- composition.RegisterUnique();
- }
- }
-}
diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
index bd20769d45..5b031c095e 100644
--- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
+++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
@@ -18,6 +18,7 @@
+
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
similarity index 97%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
index 92af822836..57ad83d4ba 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
@@ -5,7 +5,7 @@ using Microsoft.Extensions.Hosting;
using Umbraco.Core;
using Umbraco.Core.Hosting;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
public class AspNetCoreApplicationShutdownRegistry : IApplicationShutdownRegistry
{
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreBackOfficeInfo.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
similarity index 72%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreBackOfficeInfo.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
index ba12b64dfe..39b1d7ff4e 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreBackOfficeInfo.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
@@ -1,7 +1,7 @@
using Umbraco.Core;
using Umbraco.Core.Configuration;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
public class AspNetCoreBackOfficeInfo : IBackOfficeInfo
{
@@ -10,7 +10,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
GetAbsoluteUrl = globalSettings.UmbracoPath;
}
- public string GetAbsoluteUrl { get; }
+ public string GetAbsoluteUrl { get; } // TODO make absolute
}
}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
similarity index 98%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
index 6f1298918d..c24c2c4698 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
@@ -6,16 +6,16 @@ using Microsoft.AspNetCore.Http;
using Umbraco.Core;
using Umbraco.Core.Configuration;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
public class AspNetCoreHostingEnvironment : Umbraco.Core.Hosting.IHostingEnvironment
{
-
+
private readonly IHostingSettings _hostingSettings;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
-
+
private string _localTempPath;
public AspNetCoreHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
@@ -103,7 +103,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
return applicationPath.Add(segment).Value;
}
-
+
}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreIpResolver.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
similarity index 91%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreIpResolver.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
index cee43757d8..863d545066 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreIpResolver.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Http;
using Umbraco.Net;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
public class AspNetIpResolver : IIpResolver
{
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreMarchal.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
similarity index 88%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreMarchal.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
index 247666090e..af23d092e9 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreMarchal.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
@@ -2,7 +2,7 @@ using System;
using System.Runtime.InteropServices;
using Umbraco.Core.Diagnostics;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
public class AspNetCoreMarchal : IMarchal
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreSessionIdResolver.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs
similarity index 94%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreSessionIdResolver.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs
index cafb02d367..818a39fac5 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreSessionIdResolver.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Http.Features;
using Umbraco.Net;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
internal class AspNetCoreSessionIdResolver : ISessionIdResolver
{
@@ -13,7 +13,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
_httpContextAccessor = httpContextAccessor;
}
-
+
public string SessionId
{
get
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs
similarity index 81%
rename from src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs
rename to src/Umbraco.Web.Common/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs
index 0dca3edec8..38d78860b0 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs
@@ -1,11 +1,12 @@
+using System;
using System.Threading;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Umbraco.Net;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.AspNetCore
{
- public class AspNetCoreUmbracoApplicationLifetime : IUmbracoApplicationLifetime
+ public class AspNetCoreUmbracoApplicationLifetime : IUmbracoApplicationLifetime, IUmbracoApplicationLifetimeManager
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
@@ -32,5 +33,11 @@ namespace Umbraco.Web.BackOffice.AspNetCore
Thread.CurrentPrincipal = null;
_hostApplicationLifetime.StopApplication();
}
+
+ public void InvokeApplicationInit()
+ {
+ ApplicationInit?.Invoke(this, EventArgs.Empty);
+ }
+ public event EventHandler ApplicationInit;
}
}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs
similarity index 86%
rename from src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs
rename to src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs
index d747cb349a..6f2b31bac1 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs
+++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Umbraco.Composing;
using Umbraco.Configuration;
using Umbraco.Core;
using Umbraco.Core.Cache;
@@ -16,10 +17,11 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Logging.Serilog;
using Umbraco.Core.Persistence;
using Umbraco.Core.Runtime;
+using Umbraco.Web.Common.AspNetCore;
+using Umbraco.Web.Common.Runtime.Profiler;
-namespace Umbraco.Web.BackOffice.AspNetCore
+namespace Umbraco.Web.Common.Extensions
{
- // TODO: Move to Umbraco.Web.Common
public static class UmbracoCoreServiceCollectionExtensions
{
///
@@ -69,7 +71,8 @@ namespace Umbraco.Web.BackOffice.AspNetCore
public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IRegister umbContainer, Assembly entryAssembly)
{
if (services is null) throw new ArgumentNullException(nameof(services));
- if (umbContainer is null) throw new ArgumentNullException(nameof(umbContainer));
+ var container = umbContainer;
+ if (container is null) throw new ArgumentNullException(nameof(container));
if (entryAssembly is null) throw new ArgumentNullException(nameof(entryAssembly));
// Special case! The generic host adds a few default services but we need to manually add this one here NOW because
@@ -95,7 +98,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
backOfficeInfo,
typeFinder);
- var factory = coreRuntime.Configure(umbContainer);
+ var factory = coreRuntime.Configure(container);
return services;
}
@@ -151,9 +154,26 @@ namespace Umbraco.Web.BackOffice.AspNetCore
new AspNetCoreMarchal());
backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings);
- profiler = new LogProfiler(logger);
+ profiler = GetWebProfiler(hostingEnvironment, httpContextAccessor);
+
+ Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler);
}
+ private static IProfiler GetWebProfiler(Umbraco.Core.Hosting.IHostingEnvironment hostingEnvironment, IHttpContextAccessor httpContextAccessor)
+ {
+ // create and start asap to profile boot
+ if (!hostingEnvironment.IsDebugMode)
+ {
+ // should let it be null, that's how MiniProfiler is meant to work,
+ // but our own IProfiler expects an instance so let's get one
+ return new VoidProfiler();
+ }
+
+ var webProfiler = new WebProfiler(httpContextAccessor);
+ webProfiler.StartBoot();
+
+ return webProfiler;
+ }
private class AspNetCoreBootPermissionsChecker : IUmbracoBootPermissionChecker
{
public void ThrowIfNotPermissions()
@@ -162,6 +182,6 @@ namespace Umbraco.Web.BackOffice.AspNetCore
}
}
-
+
}
}
diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoRequestApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoRequestApplicationBuilderExtensions.cs
new file mode 100644
index 0000000000..8278c99bf5
--- /dev/null
+++ b/src/Umbraco.Web.Common/Extensions/UmbracoRequestApplicationBuilderExtensions.cs
@@ -0,0 +1,24 @@
+using System;
+using Microsoft.AspNetCore.Builder;
+using StackExchange.Profiling;
+using Umbraco.Web.Common.Middleware;
+
+namespace Umbraco.Web.Common.Extensions
+{
+ public static class UmbracoRequestApplicationBuilderExtensions
+ {
+ public static IApplicationBuilder UseUmbracoRequest(this IApplicationBuilder app)
+ {
+ if (app == null)
+ {
+ throw new ArgumentNullException(nameof(app));
+ }
+
+
+ app.UseMiddleware();
+ app.UseMiddleware();
+ return app;
+ }
+ }
+
+}
diff --git a/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetime.cs b/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetime.cs
new file mode 100644
index 0000000000..616a75bfe7
--- /dev/null
+++ b/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetime.cs
@@ -0,0 +1,11 @@
+using System;
+using Microsoft.AspNetCore.Http;
+
+namespace Umbraco.Web.Common.Lifetime
+{
+ public interface IUmbracoRequestLifetime
+ {
+ event EventHandler RequestStart;
+ event EventHandler RequestEnd;
+ }
+}
diff --git a/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetimeManager.cs b/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetimeManager.cs
new file mode 100644
index 0000000000..e4c671c2d3
--- /dev/null
+++ b/src/Umbraco.Web.Common/Lifetime/IUmbracoRequestLifetimeManager.cs
@@ -0,0 +1,10 @@
+using Microsoft.AspNetCore.Http;
+
+namespace Umbraco.Web.Common.Lifetime
+{
+ public interface IUmbracoRequestLifetimeManager
+ {
+ void InitRequest(HttpContext context);
+ void EndRequest(HttpContext context);
+ }
+}
diff --git a/src/Umbraco.Web.Common/Lifetime/UmbracoRequestLifetime.cs b/src/Umbraco.Web.Common/Lifetime/UmbracoRequestLifetime.cs
new file mode 100644
index 0000000000..43810a9e66
--- /dev/null
+++ b/src/Umbraco.Web.Common/Lifetime/UmbracoRequestLifetime.cs
@@ -0,0 +1,21 @@
+using System;
+using Microsoft.AspNetCore.Http;
+
+namespace Umbraco.Web.Common.Lifetime
+{
+ public class UmbracoRequestLifetime : IUmbracoRequestLifetime, IUmbracoRequestLifetimeManager
+ {
+ public event EventHandler RequestStart;
+ public event EventHandler RequestEnd;
+
+ public void InitRequest(HttpContext context)
+ {
+ RequestStart?.Invoke(this, context);
+ }
+
+ public void EndRequest(HttpContext context)
+ {
+ RequestEnd?.Invoke(this, context);
+ }
+ }
+}
diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs
new file mode 100644
index 0000000000..93461fc1d5
--- /dev/null
+++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Umbraco.Web.Common.Lifetime;
+
+namespace Umbraco.Web.Common.Middleware
+{
+ public class UmbracoRequestMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly IUmbracoRequestLifetimeManager _umbracoRequestLifetimeManager;
+ public UmbracoRequestMiddleware(RequestDelegate next, IUmbracoRequestLifetimeManager umbracoRequestLifetimeManager)
+ {
+ _next = next;
+ _umbracoRequestLifetimeManager = umbracoRequestLifetimeManager;
+ }
+
+ public async Task InvokeAsync(HttpContext context)
+ {
+ _umbracoRequestLifetimeManager.InitRequest(context);
+ await _next(context);
+ _umbracoRequestLifetimeManager.EndRequest(context);
+ }
+ }
+
+}
diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComponent.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComponent.cs
new file mode 100644
index 0000000000..991dce55e6
--- /dev/null
+++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComponent.cs
@@ -0,0 +1,29 @@
+using Microsoft.Extensions.Hosting;
+using Umbraco.Core.Composing;
+using Umbraco.Net;
+
+namespace Umbraco.Web.Common.Runtime
+{
+ public sealed class AspNetCoreComponent : IComponent
+ {
+ private readonly IHostApplicationLifetime _hostApplicationLifetime;
+ private readonly IUmbracoApplicationLifetimeManager _umbracoApplicationLifetimeManager;
+
+ public AspNetCoreComponent(IHostApplicationLifetime hostApplicationLifetime, IUmbracoApplicationLifetimeManager umbracoApplicationLifetimeManager)
+ {
+ _hostApplicationLifetime = hostApplicationLifetime;
+ _umbracoApplicationLifetimeManager = umbracoApplicationLifetimeManager;
+ }
+
+ public void Initialize()
+ {
+ _hostApplicationLifetime.ApplicationStarted.Register(() => {
+ _umbracoApplicationLifetimeManager.InvokeApplicationInit();
+ });
+ }
+
+ public void Terminate()
+ {
+ }
+ }
+}
diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs
new file mode 100644
index 0000000000..6c5aeb1b56
--- /dev/null
+++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs
@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.Http;
+using Umbraco.Core;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Hosting;
+using Umbraco.Net;
+using Umbraco.Core.Runtime;
+using Umbraco.Web.Common.AspNetCore;
+using Umbraco.Web.Common.Lifetime;
+
+namespace Umbraco.Web.Common.Runtime
+{
+ ///
+ /// Adds/replaces AspNetCore specific services
+ ///
+ [ComposeBefore(typeof(ICoreComposer))]
+ [ComposeAfter(typeof(CoreInitialComposer))]
+ public class AspNetCoreComposer : ComponentComposer, IComposer
+ {
+ public new void Compose(Composition composition)
+ {
+ base.Compose(composition);
+
+ // AspNetCore specific services
+ composition.RegisterUnique();
+
+ // Our own netcore implementations
+ composition.RegisterUnique();
+ composition.RegisterUnique(factory => factory.GetInstance());
+ composition.RegisterUnique(factory => factory.GetInstance());
+
+ composition.RegisterUnique();
+
+ // The umbraco request lifetime
+ composition.RegisterUnique();
+ composition.RegisterUnique(factory => factory.GetInstance());
+ composition.RegisterUnique(factory => factory.GetInstance());
+ }
+ }
+}
diff --git a/src/Umbraco.Web.Common/Runtime/Profiler/WebProfiler.cs b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfiler.cs
new file mode 100644
index 0000000000..bdbc6f164d
--- /dev/null
+++ b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfiler.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Extensions;
+using StackExchange.Profiling;
+using StackExchange.Profiling.Internal;
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+
+namespace Umbraco.Web.Common.Runtime.Profiler
+{
+ public class WebProfiler : IProfiler
+ {
+ private MiniProfiler _startupProfiler;
+
+ private readonly IHttpContextAccessor _httpContextAccessor;
+ private int _first;
+
+ public WebProfiler(IHttpContextAccessor httpContextAccessor)
+ {
+ // create our own provider, which can provide a profiler even during boot
+ _httpContextAccessor = httpContextAccessor;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// Normally we would call MiniProfiler.Current.RenderIncludes(...), but because the requeststate is not set, this method does not work.
+ /// We fake the requestIds from the RequestState here.
+ ///
+ public string Render()
+ {
+
+ var profiler = MiniProfiler.Current;
+ if (profiler == null) return string.Empty;
+
+ var context = _httpContextAccessor.HttpContext;
+
+ var path = (profiler.Options as MiniProfilerOptions)?.RouteBasePath.Value.EnsureTrailingSlash();
+
+ var result = StackExchange.Profiling.Internal.Render.Includes(
+ profiler,
+ path: context.Request.PathBase + path,
+ isAuthorized: true,
+ requestIDs: new List{ profiler.Id },
+ position: RenderPosition.Right,
+ showTrivial: profiler.Options.PopupShowTrivial,
+ showTimeWithChildren: profiler.Options.PopupShowTimeWithChildren,
+ maxTracesToShow: profiler.Options.PopupMaxTracesToShow,
+ showControls:profiler.Options.ShowControls,
+ startHidden: profiler.Options.PopupStartHidden);
+
+ return result;
+ }
+
+ public IDisposable Step(string name)
+ {
+ return MiniProfiler.Current?.Step(name);
+ }
+
+ public void Start()
+ {
+ MiniProfiler.StartNew();
+ }
+
+ public void StartBoot()
+ {
+ _startupProfiler = MiniProfiler.StartNew("Startup Profiler");
+ }
+
+ public void StopBoot()
+ {
+ _startupProfiler.Stop();
+ }
+
+ public void Stop(bool discardResults = false)
+ {
+ MiniProfiler.Current?.Stop(discardResults);
+ }
+
+
+ public void UmbracoApplicationBeginRequest(HttpContext context)
+ {
+ if (ShouldProfile(context.Request))
+ {
+ Start();
+ }
+ }
+
+ public void UmbracoApplicationEndRequest(HttpContext context)
+ {
+ if (ShouldProfile(context.Request))
+ {
+ Stop();
+
+ // if this is the first request, append the startup profiler
+ var first = Interlocked.Exchange(ref _first, 1) == 0;
+ if (first)
+ {
+
+ var startupDuration = _startupProfiler.Root.DurationMilliseconds.GetValueOrDefault();
+ MiniProfiler.Current.DurationMilliseconds += startupDuration;
+ MiniProfiler.Current.GetTimingHierarchy().First().DurationMilliseconds += startupDuration;
+ MiniProfiler.Current.Root.AddChild(_startupProfiler.Root);
+
+ _startupProfiler = null;
+ }
+ }
+ }
+
+ private static bool ShouldProfile(HttpRequest request)
+ {
+ if (new Uri(request.GetEncodedUrl(), UriKind.RelativeOrAbsolute).IsClientSideRequest()) return false;
+ if (bool.TryParse(request.Query["umbDebug"], out var umbDebug)) return umbDebug;
+ if (bool.TryParse(request.Headers["X-UMB-DEBUG"], out var xUmbDebug)) return xUmbDebug;
+ if (bool.TryParse(request.Cookies["UMB-DEBUG"], out var cUmbDebug)) return cUmbDebug;
+ return false;
+ }
+ }
+}
diff --git a/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComponent.cs b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComponent.cs
new file mode 100644
index 0000000000..a36753e634
--- /dev/null
+++ b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComponent.cs
@@ -0,0 +1,59 @@
+using System;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Logging;
+using Umbraco.Net;
+using Umbraco.Web.Common.Lifetime;
+using Umbraco.Web.Common.Middleware;
+
+namespace Umbraco.Web.Common.Runtime.Profiler
+{
+ internal sealed class WebProfilerComponent : IComponent
+ {
+ private readonly bool _profile;
+ private readonly WebProfiler _profiler;
+ private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime;
+ private readonly IUmbracoRequestLifetime _umbracoRequestLifetime;
+
+ public WebProfilerComponent(IProfiler profiler, ILogger logger, IUmbracoRequestLifetime umbracoRequestLifetime,
+ IUmbracoApplicationLifetime umbracoApplicationLifetime)
+ {
+ _umbracoRequestLifetime = umbracoRequestLifetime;
+ _umbracoApplicationLifetime = umbracoApplicationLifetime;
+ _profile = true;
+
+ // although registered in WebRuntime.Compose, ensure that we have not
+ // been replaced by another component, and we are still "the" profiler
+ _profiler = profiler as WebProfiler;
+ if (_profiler != null) return;
+
+ // if VoidProfiler was registered, let it be known
+ if (profiler is VoidProfiler)
+ logger.Info(
+ "Profiler is VoidProfiler, not profiling (must run debug mode to profile).");
+ _profile = false;
+ }
+
+ public void Initialize()
+ {
+ if (!_profile) return;
+
+ // bind to ApplicationInit - ie execute the application initialization for *each* application
+ // it would be a mistake to try and bind to the current application events
+ _umbracoApplicationLifetime.ApplicationInit += InitializeApplication;
+ }
+
+ public void Terminate()
+ {
+ }
+
+ private void InitializeApplication(object sender, EventArgs args)
+ {
+ _umbracoRequestLifetime.RequestStart +=
+ (sender, context) => _profiler.UmbracoApplicationBeginRequest(context);
+ _umbracoRequestLifetime.RequestEnd += (sender, context) => _profiler.UmbracoApplicationEndRequest(context);
+
+ // Stop the profiling of the booting process
+ _profiler.StopBoot();
+ }
+ }
+}
diff --git a/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComposer.cs b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComposer.cs
new file mode 100644
index 0000000000..688a3e5c28
--- /dev/null
+++ b/src/Umbraco.Web.Common/Runtime/Profiler/WebProfilerComposer.cs
@@ -0,0 +1,8 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Web.Common.Runtime.Profiler
+{
+ internal class WebProfilerComposer : ComponentComposer, ICoreComposer
+ {
+ }
+}
diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
new file mode 100644
index 0000000000..2cf6790484
--- /dev/null
+++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
@@ -0,0 +1,23 @@
+
+
+
+ netcoreapp3.1
+ Library
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json b/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json
index b145249bb5..27f36121ac 100644
--- a/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json
+++ b/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json
@@ -1,7 +1,7 @@
{
"iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:36804",
"sslPort": 44354
@@ -15,10 +15,11 @@
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
- "Umbraco.Web.UI.BackOffice": {
+ "Umbraco.Web.UI.NetCore": {
"commandName": "Project",
- "launchBrowser": true,
- "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "launchBrowser": false,
+ "applicationUrl": "https://localhost:44354;http://localhost:9000",
+
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs
index 2753676452..3906f1c8e9 100644
--- a/src/Umbraco.Web.UI.NetCore/Startup.cs
+++ b/src/Umbraco.Web.UI.NetCore/Startup.cs
@@ -5,10 +5,19 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using StackExchange.Profiling;
+using Umbraco.Composing;
+using Umbraco.Core;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.IO;
using Umbraco.Web.BackOffice.AspNetCore;
+using Umbraco.Web.Common.AspNetCore;
+using Umbraco.Web.Common.Extensions;
+using Umbraco.Web.Common.Runtime.Profiler;
using Umbraco.Web.Website.AspNetCore;
@@ -40,24 +49,36 @@ namespace Umbraco.Web.UI.BackOffice
services.AddUmbracoConfiguration(_config);
services.AddUmbracoCore(_webHostEnvironment);
services.AddUmbracoWebsite();
+
+ services.AddMvc();
+ services.AddMiniProfiler(options =>
+ {
+ options.ShouldProfile = request => false; // WebProfiler determine and start profiling. We should not use the MiniProfilerMiddleware to also profile
+ });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+
+ // app.UseMiniProfiler();
+ app.UseUmbracoRequest();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
+ app.UseUmbracoCore();
app.UseUmbracoWebsite();
app.UseUmbracoBackOffice();
app.UseRouting();
-
app.UseEndpoints(endpoints =>
{
- endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); });
+ endpoints.MapGet("/", async context =>
+ {
+ await context.Response.WriteAsync($"Hello World!{Current.Profiler.Render()}");
+ });
});
}
}
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 ca7c3e26fa..dc148d8d1f 100644
--- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj
+++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj
@@ -7,6 +7,7 @@
+
@@ -14,9 +15,4 @@
-
- <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.hash" />
- <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.list" />
-
-
diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json
index 1c89647efa..2448ae0aa9 100644
--- a/src/Umbraco.Web.UI.NetCore/appsettings.json
+++ b/src/Umbraco.Web.UI.NetCore/appsettings.json
@@ -12,6 +12,9 @@
"AllowedHosts": "*",
"Umbraco": {
"CMS": {
+ "Hosting": {
+ "Debug": true
+ },
"Imaging": {
"Resize": {
"MaxWidth": 5000,
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index fe11a8d9aa..0c0e6aee50 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -101,7 +101,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
3.4.0
diff --git a/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs b/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs
index 245e8ea374..8c43293ad7 100644
--- a/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs
+++ b/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs
@@ -1,16 +1,19 @@
+using System;
using System.Threading;
using System.Web;
using Umbraco.Net;
namespace Umbraco.Web.AspNet
{
- public class AspNetUmbracoApplicationLifetime : IUmbracoApplicationLifetime
+ public class AspNetUmbracoApplicationLifetime : IUmbracoApplicationLifetimeManager
{
private readonly IHttpContextAccessor _httpContextAccessor;
public AspNetUmbracoApplicationLifetime(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
+
+ UmbracoApplicationBase.ApplicationInit += ApplicationInit;
}
public bool IsRestarting { get; set; }
@@ -30,5 +33,11 @@ namespace Umbraco.Web.AspNet
Thread.CurrentPrincipal = null;
HttpRuntime.UnloadAppDomain();
}
+
+ public event EventHandler ApplicationInit;
+ public void InvokeApplicationInit()
+ {
+ ApplicationInit?.Invoke(this, EventArgs.Empty);
+ }
}
}
diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs
index e39d1658a2..09076400de 100644
--- a/src/Umbraco.Web/Editors/BackOfficeController.cs
+++ b/src/Umbraco.Web/Editors/BackOfficeController.cs
@@ -104,8 +104,11 @@ namespace Umbraco.Web.Editors
public async Task Default()
{
return await RenderDefaultOrProcessExternalLoginAsync(
- () => View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings,_ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)),
- () => View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)));
+ () =>
+ View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings,_ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)),
+ () =>
+ View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings))
+ );
}
[HttpGet]
diff --git a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
index f5a2ca8ac8..fdec5bfa2e 100644
--- a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
+++ b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
@@ -60,12 +60,14 @@ namespace Umbraco.Web.Install.InstallSteps
var membershipUser = await userManager.FindByIdAsync(Constants.Security.SuperUserId);
if (membershipUser == null)
{
- throw new InvalidOperationException($"No user found in membership provider with id of {Constants.Security.SuperUserId}.");
+ throw new InvalidOperationException(
+ $"No user found in membership provider with id of {Constants.Security.SuperUserId}.");
}
//To change the password here we actually need to reset it since we don't have an old one to use to change
var resetToken = await userManager.GeneratePasswordResetTokenAsync(membershipUser.Id);
- var resetResult = await userManager.ChangePasswordWithResetAsync(membershipUser.Id, resetToken, user.Password.Trim());
+ var resetResult =
+ await userManager.ChangePasswordWithResetAsync(membershipUser.Id, resetToken, user.Password.Trim());
if (!resetResult.Succeeded)
{
throw new InvalidOperationException("Could not reset password: " + string.Join(", ", resetResult.Errors));
diff --git a/src/Umbraco.Web/Logging/WebProfiler.cs b/src/Umbraco.Web/Logging/WebProfiler.cs
index 512edb2296..e390950c0b 100755
--- a/src/Umbraco.Web/Logging/WebProfiler.cs
+++ b/src/Umbraco.Web/Logging/WebProfiler.cs
@@ -29,7 +29,7 @@ namespace Umbraco.Web.Logging
MiniProfiler.Configure(new MiniProfilerOptions
{
SqlFormatter = new SqlServerFormatter(),
- StackMaxLength = 5000,
+ StackMaxLength = 5000,
ProfilerProvider = _provider
});
}
diff --git a/src/Umbraco.Web/Logging/WebProfilerComposer.cs b/src/Umbraco.Web/Logging/WebProfilerComposer.cs
index 5834dd9dd4..283c519b44 100644
--- a/src/Umbraco.Web/Logging/WebProfilerComposer.cs
+++ b/src/Umbraco.Web/Logging/WebProfilerComposer.cs
@@ -1,4 +1,4 @@
-using Umbraco.Core.Composing;
+ using Umbraco.Core.Composing;
namespace Umbraco.Web.Logging
{
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 4b4f06ad2a..b0121ccbc1 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -92,7 +92,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/src/umbraco.sln b/src/umbraco.sln
index 09423ec00e..c0a6103e31 100644
--- a/src/umbraco.sln
+++ b/src/umbraco.sln
@@ -125,7 +125,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Integration",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Common", "Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.UnitTests", "Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Web.Common", "Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{839D3048-9718-4907-BDE0-7CD63D364383}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.UnitTests", "Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{3A003230-60B4-4C15-9470-9A77F1BAC1D9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -167,10 +169,6 @@ Global
{FBE7C065-DAC0-4025-A78B-63B24D3AB00B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBE7C065-DAC0-4025-A78B-63B24D3AB00B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBE7C065-DAC0-4025-A78B-63B24D3AB00B}.Release|Any CPU.Build.0 = Release|Any CPU
- {9102ABDF-E537-4E46-B525-C9ED4833EED0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9102ABDF-E537-4E46-B525-C9ED4833EED0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9102ABDF-E537-4E46-B525-C9ED4833EED0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9102ABDF-E537-4E46-B525-C9ED4833EED0}.Release|Any CPU.Build.0 = Release|Any CPU
{33085570-9BF2-4065-A9B0-A29D920D13BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33085570-9BF2-4065-A9B0-A29D920D13BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33085570-9BF2-4065-A9B0-A29D920D13BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -207,6 +205,14 @@ Global
{A499779C-1B3B-48A8-B551-458E582E6E96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A499779C-1B3B-48A8-B551-458E582E6E96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A499779C-1B3B-48A8-B551-458E582E6E96}.Release|Any CPU.Build.0 = Release|Any CPU
+ {839D3048-9718-4907-BDE0-7CD63D364383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {839D3048-9718-4907-BDE0-7CD63D364383}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {839D3048-9718-4907-BDE0-7CD63D364383}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {839D3048-9718-4907-BDE0-7CD63D364383}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A003230-60B4-4C15-9470-9A77F1BAC1D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3A003230-60B4-4C15-9470-9A77F1BAC1D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A003230-60B4-4C15-9470-9A77F1BAC1D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3A003230-60B4-4C15-9470-9A77F1BAC1D9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -219,10 +225,10 @@ Global
{53594E5B-64A2-4545-8367-E3627D266AE8} = {FD962632-184C-4005-A5F3-E705D92FC645}
{3A33ADC9-C6C0-4DB1-A613-A9AF0210DF3D} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{C7311C00-2184-409B-B506-52A5FAEA8736} = {FD962632-184C-4005-A5F3-E705D92FC645}
- {9102ABDF-E537-4E46-B525-C9ED4833EED0} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{FB5676ED-7A69-492C-B802-E7B24144C0FC} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{D6319409-777A-4BD0-93ED-B2DFD805B32C} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{A499779C-1B3B-48A8-B551-458E582E6E96} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
+ {3A003230-60B4-4C15-9470-9A77F1BAC1D9} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}