diff --git a/src/Umbraco.Core/CompositionExtensions_Uniques.cs b/src/Umbraco.Core/CompositionExtensions_Uniques.cs index 52f1ce7ecd..8352eb33ec 100644 --- a/src/Umbraco.Core/CompositionExtensions_Uniques.cs +++ b/src/Umbraco.Core/CompositionExtensions_Uniques.cs @@ -31,5 +31,20 @@ namespace Umbraco.Core /// public static void RegisterUnique(this Composition composition, TService instance) => composition.RegisterUnique(typeof(TService), instance); + + + + /// + /// Registers a unique service with an implementation type. + /// + public static void RegisterMultipleUnique(this Composition composition) + where TImplementing : class, TService1, TService2 + where TService1 : class + where TService2 : class + { + composition.RegisterUnique(); + composition.RegisterUnique(factory => factory.GetInstance()); + composition.RegisterUnique(factory => factory.GetInstance()); + } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Session/ISessionManager.cs b/src/Umbraco.Core/Session/ISessionManager.cs index f3a47202ee..642122f2d3 100644 --- a/src/Umbraco.Core/Session/ISessionManager.cs +++ b/src/Umbraco.Core/Session/ISessionManager.cs @@ -2,7 +2,7 @@ namespace Umbraco.Core.Session { public interface ISessionManager { - object GetSessionValue(string sessionName); - void SetSessionValue(string sessionName, object value); + string GetSessionValue(string sessionName); + void SetSessionValue(string sessionName, string value); } } diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs new file mode 100644 index 0000000000..79190a6776 --- /dev/null +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs @@ -0,0 +1,46 @@ +using System; +using Microsoft.AspNetCore.Http; +using Umbraco.Core.Cookie; + +namespace Umbraco.Web.Common.AspNetCore +{ + public class AspNetCoreCookieManager : ICookieManager + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public AspNetCoreCookieManager(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + public void ExpireCookie(string cookieName) + { + var httpContext = _httpContextAccessor.HttpContext; + + if (httpContext is null) return; + + var cookieValue = httpContext.Request.Cookies[cookieName]; + + httpContext.Response.Cookies.Append(cookieName, cookieValue, new CookieOptions() + { + Expires = DateTime.Now.AddYears(-1) + }); + } + + public string GetCookieValue(string cookieName) + { + return _httpContextAccessor.HttpContext?.Request.Cookies[cookieName]; + } + + public void SetCookieValue(string cookieName, string value) + { + _httpContextAccessor.HttpContext?.Response.Cookies.Append(cookieName, value); + } + + public bool HasCookie(string cookieName) + { + return !(GetCookieValue(cookieName) is null); + } + + } +} diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs deleted file mode 100644 index 818a39fac5..0000000000 --- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionIdResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; -using Umbraco.Net; - -namespace Umbraco.Web.Common.AspNetCore -{ - internal class AspNetCoreSessionIdResolver : ISessionIdResolver - { - private readonly IHttpContextAccessor _httpContextAccessor; - - public AspNetCoreSessionIdResolver(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - - - public string SessionId - { - get - { - var httpContext = _httpContextAccessor?.HttpContext; - // If session isn't enabled this will throw an exception so we check - var sessionFeature = httpContext?.Features.Get(); - return sessionFeature != null - ? httpContext?.Session?.Id - : "0"; - } - } - } -} diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs new file mode 100644 index 0000000000..08b4a46aef --- /dev/null +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Umbraco.Core.Session; +using Umbraco.Net; + +namespace Umbraco.Web.Common.AspNetCore +{ + internal class AspNetCoreSessionManager : ISessionIdResolver, ISessionManager + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public AspNetCoreSessionManager(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + + /// + /// If session isn't enabled this will throw an exception so we check + /// + private bool IsSessionsAvailable => !(_httpContextAccessor.HttpContext?.Features.Get() is null); + + public string SessionId + { + get + { + var httpContext = _httpContextAccessor?.HttpContext; + + return IsSessionsAvailable + ? httpContext?.Session?.Id + : "0"; + } + } + + public string GetSessionValue(string sessionName) + { + if(!IsSessionsAvailable) return null; + return _httpContextAccessor.HttpContext?.Session.GetString(sessionName); + } + + + public void SetSessionValue(string sessionName, string value) + { + if(!IsSessionsAvailable) return; + _httpContextAccessor.HttpContext?.Session.SetString(sessionName, value); + } + } +} diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index d8f8fc1aed..916e886f50 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -164,7 +164,7 @@ namespace Umbraco.Web.Common.Extensions hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor); ioHelper = new IOHelper(hostingEnvironment, globalSettings); logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, - new AspNetCoreSessionIdResolver(httpContextAccessor), + new AspNetCoreSessionManager(httpContextAccessor), // TODO: We need to avoid this, surely there's a way? See ContainerTests.BuildServiceProvider_Before_Host_Is_Configured () => services.BuildServiceProvider().GetService(), coreDebug, ioHelper, new AspNetCoreMarchal()); diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index 4080c5a8fe..fb70790143 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -1,12 +1,14 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Cookie; using Umbraco.Core.Hosting; using Umbraco.Core.Media; using Umbraco.Core.Models.PublishedContent; using Umbraco.Net; using Umbraco.Core.Runtime; using Umbraco.Core.Security; +using Umbraco.Core.Session; using Umbraco.Infrastructure.Media; using Umbraco.Web.Common.AspNetCore; using Umbraco.Web.Common.Lifetime; @@ -39,15 +41,18 @@ namespace Umbraco.Web.Common.Runtime composition.RegisterUnique(); // The umbraco request lifetime - composition.RegisterUnique(); - composition.RegisterUnique(factory => factory.GetInstance()); - composition.RegisterUnique(factory => factory.GetInstance()); + composition.RegisterMultipleUnique(); //Password hasher composition.RegisterUnique(); + composition.RegisterUnique(); + + composition.RegisterMultipleUnique(); + + composition.RegisterUnique(); } } diff --git a/src/Umbraco.Web/AspNet/AspNetSessionManager.cs b/src/Umbraco.Web/AspNet/AspNetSessionManager.cs index f81daadb0a..d975dac528 100644 --- a/src/Umbraco.Web/AspNet/AspNetSessionManager.cs +++ b/src/Umbraco.Web/AspNet/AspNetSessionManager.cs @@ -11,13 +11,15 @@ namespace Umbraco.Web.AspNet { } - public object GetSessionValue(string sessionName) + public string GetSessionValue(string sessionName) { - return HttpContext.Current.Session[sessionName]; + return HttpContext.Current?.Session[sessionName]?.ToString(); } - public void SetSessionValue(string sessionName, object value) + public void SetSessionValue(string sessionName, string value) { + var httpContext = HttpContext.Current; + if (httpContext is null) return; HttpContext.Current.Session[sessionName] = value; } diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs index d5f3ba244b..21a242ee17 100644 --- a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs @@ -29,7 +29,7 @@ namespace Umbraco.Web.Composing.CompositionExtensions .Add() .Add() .Add() - .Add();; + .Add(); composition.Register(); composition.Register(); diff --git a/src/Umbraco.Web/Macros/MacroRenderer.cs b/src/Umbraco.Web/Macros/MacroRenderer.cs index 624395049e..b79922474b 100644 --- a/src/Umbraco.Web/Macros/MacroRenderer.cs +++ b/src/Umbraco.Web/Macros/MacroRenderer.cs @@ -403,7 +403,7 @@ namespace Umbraco.Web.Macros attributeValue = _requestAccessor.GetRequestValue(name); break; case '%': - attributeValue = _sessionManager.GetSessionValue(name)?.ToString(); + attributeValue = _sessionManager.GetSessionValue(name); if (string.IsNullOrEmpty(attributeValue)) attributeValue = _cookieManager.GetCookieValue(name); break; diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index e3d21d2dd3..45fc6b2b69 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -3,53 +3,31 @@ using System.Web.Security; using Examine; using Microsoft.AspNet.SignalR; using Umbraco.Core; -using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Cookie; using Umbraco.Core.Dictionary; -using Umbraco.Core.Events; using Umbraco.Core.Hosting; using Umbraco.Core.Install; -using Umbraco.Core.Migrations.PostMigrations; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Runtime; using Umbraco.Core.Security; using Umbraco.Core.Services; -using Umbraco.Core.Sync; -using Umbraco.Web.Actions; -using Umbraco.Web.Cache; using Umbraco.Web.Composing.CompositionExtensions; -using Umbraco.Web.ContentApps; -using Umbraco.Web.Editors; -using Umbraco.Web.Features; -using Umbraco.Web.HealthCheck; using Umbraco.Web.Hosting; using Umbraco.Web.Install; using Umbraco.Web.Macros; -using Umbraco.Web.Media.EmbedProviders; -using Umbraco.Web.Models.PublishedContent; using Umbraco.Web.Mvc; using Umbraco.Web.PublishedCache; -using Umbraco.Web.Routing; -using Umbraco.Web.Search; -using Umbraco.Web.Sections; using Umbraco.Web.Security; using Umbraco.Web.Security.Providers; -using Umbraco.Web.Services; using Umbraco.Web.SignalR; using Umbraco.Web.Templates; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -using Umbraco.Web.PropertyEditors; -using Umbraco.Examine; using Umbraco.Net; using Umbraco.Core.Request; using Umbraco.Core.Session; using Umbraco.Web.AspNet; -using Umbraco.Core.Media; -using Umbraco.Infrastructure.Media; namespace Umbraco.Web.Runtime { @@ -66,9 +44,7 @@ namespace Umbraco.Web.Runtime composition.Register(); composition.Register(); - composition.Register(Lifetime.Singleton); - composition.Register(factory => factory.GetInstance(), Lifetime.Singleton); - composition.Register(factory => factory.GetInstance(), Lifetime.Singleton); + composition.Register(Lifetime.Singleton); @@ -76,8 +52,7 @@ namespace Umbraco.Web.Runtime composition.Register(); composition.Register(Lifetime.Singleton); - composition.RegisterUnique(); // required for hybrid accessors - composition.RegisterUnique(); + composition.ComposeWebMappingProfiles(); @@ -151,12 +126,17 @@ namespace Umbraco.Web.Runtime .AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x))); - // Config manipulator - composition.RegisterUnique(); - //ApplicationShutdownRegistry + // STUFF that do not have to be moved to .NET CORE + //---------------------------------------- + composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); // required for hybrid accessors + composition.Register(Lifetime.Singleton); + composition.Register(factory => factory.GetInstance(), Lifetime.Singleton); + composition.Register(factory => factory.GetInstance(), Lifetime.Singleton); } }