From 9bf6ac5718b24dbac5be0d1a6abb690cd35e2b4f Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 26 May 2015 19:49:55 +0200 Subject: [PATCH] #4607: Refactored HttpContextAccessor to return a valid HttpContextBase instance in background tasks. --- .../Settings/Commands/SiteSettingsCommands.cs | 3 +- .../Implementation/DefaultDisplayManager.cs | 3 +- .../Environment/DefaultHostEnvironment.cs | 3 +- src/Orchard/Environment/OrchardStarter.cs | 2 +- .../Environment/WorkContextAccessor.cs | 5 +-- .../Extensions/HttpContextBaseExtensions.cs | 9 +++++ src/Orchard/Mvc/HttpContextAccessor.cs | 18 ++++++++++ src/Orchard/Mvc/IHttpContextAccessor.cs | 34 +------------------ src/Orchard/Mvc/MvcModule.cs | 8 ++--- src/Orchard/Orchard.Framework.csproj | 2 ++ .../Providers/FormsAuthenticationService.cs | 3 +- 11 files changed, 46 insertions(+), 44 deletions(-) create mode 100644 src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs create mode 100644 src/Orchard/Mvc/HttpContextAccessor.cs diff --git a/src/Orchard.Web/Core/Settings/Commands/SiteSettingsCommands.cs b/src/Orchard.Web/Core/Settings/Commands/SiteSettingsCommands.cs index d3fcb8ca6..1778d48c3 100644 --- a/src/Orchard.Web/Core/Settings/Commands/SiteSettingsCommands.cs +++ b/src/Orchard.Web/Core/Settings/Commands/SiteSettingsCommands.cs @@ -2,6 +2,7 @@ using Orchard.ContentManagement; using Orchard.Core.Settings.Models; using Orchard.Mvc; +using Orchard.Mvc.Extensions; using Orchard.Settings; using Orchard.Utility.Extensions; @@ -38,7 +39,7 @@ namespace Orchard.Core.Settings.Commands { // Retrieve request URL if BaseUrl not provided as a switch value if (string.IsNullOrEmpty(BaseUrl)) { - if (_httpContextAccessor.Current() == null) { + if (_httpContextAccessor.Current().IsBackgroundContext()) { Context.Output.WriteLine(T("No HTTP request available to determine the base url of the site")); return; } diff --git a/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs index 29563b9c9..967ae91de 100644 --- a/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs +++ b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs @@ -11,6 +11,7 @@ using Orchard.DisplayManagement.Shapes; using Orchard.Localization; using Orchard.Logging; using Orchard.Mvc; +using Orchard.Mvc.Extensions; namespace Orchard.DisplayManagement.Implementation { public class DefaultDisplayManager : IDisplayManager { @@ -61,7 +62,7 @@ namespace Orchard.DisplayManagement.Implementation { return CoerceHtmlString(context.Value); var workContext = _workContextAccessor.GetContext(); - var shapeTable = _httpContextAccessor.Current() != null + var shapeTable = !_httpContextAccessor.Current().IsBackgroundContext() ? _shapeTableLocator.Value.Lookup(workContext.CurrentTheme.Id) : _shapeTableLocator.Value.Lookup(null); diff --git a/src/Orchard/Environment/DefaultHostEnvironment.cs b/src/Orchard/Environment/DefaultHostEnvironment.cs index 37d6e6c49..b4c388029 100644 --- a/src/Orchard/Environment/DefaultHostEnvironment.cs +++ b/src/Orchard/Environment/DefaultHostEnvironment.cs @@ -3,6 +3,7 @@ using System.Web; using Orchard.Localization; using Orchard.Logging; using Orchard.Mvc; +using Orchard.Mvc.Extensions; using Orchard.Services; using Orchard.Utility.Extensions; @@ -41,7 +42,7 @@ namespace Orchard.Environment { // current request can be processed correctly. So, we redirect to the same URL, so that the // new request will come to the newly started AppDomain. var httpContext = _httpContextAccessor.Current(); - if (httpContext != null) { + if (!httpContext.IsBackgroundContext()) { // Don't redirect posts... if (httpContext.Request.RequestType == "GET") { httpContext.Response.Redirect(HttpContext.Current.Request.ToUrlString(), true /*endResponse*/); diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 66ea2a066..3dbd599d9 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -63,7 +63,7 @@ namespace Orchard.Environment { builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().InstancePerDependency(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/src/Orchard/Environment/WorkContextAccessor.cs b/src/Orchard/Environment/WorkContextAccessor.cs index a1216f644..af709d0d5 100644 --- a/src/Orchard/Environment/WorkContextAccessor.cs +++ b/src/Orchard/Environment/WorkContextAccessor.cs @@ -5,6 +5,7 @@ using System.Web; using Autofac; using Orchard.Logging; using Orchard.Mvc; +using Orchard.Mvc.Extensions; namespace Orchard.Environment { public class WorkContextAccessor : IWorkContextAccessor { @@ -31,7 +32,7 @@ namespace Orchard.Environment { public WorkContext GetContext() { var httpContext = _httpContextAccessor.Current(); - if (httpContext != null) + if (!httpContext.IsBackgroundContext()) return GetContext(httpContext); WorkContext workContext; @@ -55,7 +56,7 @@ namespace Orchard.Environment { public IWorkContextScope CreateWorkContextScope() { var httpContext = _httpContextAccessor.Current(); - if (httpContext != null) + if (!httpContext.IsBackgroundContext()) return CreateWorkContextScope(httpContext); var workLifetime = _lifetimeScope.BeginLifetimeScope("work"); diff --git a/src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs b/src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs new file mode 100644 index 000000000..9a7864887 --- /dev/null +++ b/src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs @@ -0,0 +1,9 @@ +using System.Web; + +namespace Orchard.Mvc.Extensions { + public static class HttpContextBaseExtensions { + public static bool IsBackgroundContext(this HttpContextBase httpContextBase) { + return httpContextBase == null || httpContextBase is MvcModule.HttpContextPlaceholder; + } + } +} diff --git a/src/Orchard/Mvc/HttpContextAccessor.cs b/src/Orchard/Mvc/HttpContextAccessor.cs new file mode 100644 index 000000000..ffea8ca66 --- /dev/null +++ b/src/Orchard/Mvc/HttpContextAccessor.cs @@ -0,0 +1,18 @@ +using System.Web; +using Autofac; + +namespace Orchard.Mvc { + public class HttpContextAccessor : IHttpContextAccessor { + private readonly IComponentContext _context; + + public HttpContextAccessor(IComponentContext context) { + _context = context; + } + + public HttpContextBase Current() { + HttpContextBase httpContextBase; + _context.TryResolve(out httpContextBase); + return httpContextBase; + } + } +} \ No newline at end of file diff --git a/src/Orchard/Mvc/IHttpContextAccessor.cs b/src/Orchard/Mvc/IHttpContextAccessor.cs index 91208d314..d456bce2e 100644 --- a/src/Orchard/Mvc/IHttpContextAccessor.cs +++ b/src/Orchard/Mvc/IHttpContextAccessor.cs @@ -1,39 +1,7 @@ -using System; -using System.Web; +using System.Web; namespace Orchard.Mvc { public interface IHttpContextAccessor { HttpContextBase Current(); - void Set(HttpContextBase httpContext); - } - - public class HttpContextAccessor : IHttpContextAccessor { - private HttpContextBase _httpContext; - - public HttpContextBase Current() { - var httpContext = GetStaticProperty(); - return httpContext != null ? new HttpContextWrapper(httpContext) : _httpContext; - } - - public void Set(HttpContextBase httpContext) { - _httpContext = httpContext; - } - - private HttpContext GetStaticProperty() { - var httpContext = HttpContext.Current; - if (httpContext == null) { - return null; - } - - try { - if (httpContext.Request == null) { - return null; - } - } - catch (Exception) { - return null; - } - return httpContext; - } } } diff --git a/src/Orchard/Mvc/MvcModule.cs b/src/Orchard/Mvc/MvcModule.cs index 1e0c49ce6..d6e7db059 100644 --- a/src/Orchard/Mvc/MvcModule.cs +++ b/src/Orchard/Mvc/MvcModule.cs @@ -85,7 +85,7 @@ namespace Orchard.Mvc { /// /// Standin context for background tasks. /// - class HttpContextPlaceholder : HttpContextBase { + public class HttpContextPlaceholder : HttpContextBase { private readonly Lazy _baseUrl; private readonly IDictionary _items = new Dictionary(); @@ -120,7 +120,7 @@ namespace Orchard.Mvc { } } - private class HttpResponsePlaceholder : HttpResponseBase { + public class HttpResponsePlaceholder : HttpResponseBase { public override string ApplyAppPathModifier(string virtualPath) { return virtualPath; } @@ -135,7 +135,7 @@ namespace Orchard.Mvc { /// /// standin context for background tasks. /// - class HttpRequestPlaceholder : HttpRequestBase { + public class HttpRequestPlaceholder : HttpRequestBase { private readonly Uri _uri; public HttpRequestPlaceholder(Uri uri) { @@ -217,7 +217,7 @@ namespace Orchard.Mvc { } } - class HttpBrowserCapabilitiesPlaceholder : HttpBrowserCapabilitiesBase { + public class HttpBrowserCapabilitiesPlaceholder : HttpBrowserCapabilitiesBase { public override string this[string key] { get { return ""; diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 7a3ce7d31..c53e885c9 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -317,7 +317,9 @@ + + diff --git a/src/Orchard/Security/Providers/FormsAuthenticationService.cs b/src/Orchard/Security/Providers/FormsAuthenticationService.cs index 58ad7c9b9..b31b04b5c 100644 --- a/src/Orchard/Security/Providers/FormsAuthenticationService.cs +++ b/src/Orchard/Security/Providers/FormsAuthenticationService.cs @@ -5,6 +5,7 @@ using Orchard.Environment.Configuration; using Orchard.Logging; using Orchard.ContentManagement; using Orchard.Mvc; +using Orchard.Mvc.Extensions; using Orchard.Services; namespace Orchard.Security.Providers { @@ -102,7 +103,7 @@ namespace Orchard.Security.Providers { return _signedInUser; var httpContext = _httpContextAccessor.Current(); - if (httpContext == null || !httpContext.Request.IsAuthenticated || !(httpContext.User.Identity is FormsIdentity)) { + if (httpContext.IsBackgroundContext() || !httpContext.Request.IsAuthenticated || !(httpContext.User.Identity is FormsIdentity)) { return null; }