mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Revert "Cherry picked ce630f980c7a79ae17b36598f3834c4ffd523739."
This reverts commit aba53e122d
.
Conflicts:
src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs
src/Orchard/Mvc/HttpContextAccessor.cs
src/Orchard/Mvc/IHttpContextAccessor.cs
src/Orchard/Mvc/MvcModule.cs
src/Orchard/Orchard.Framework.csproj
src/Orchard/Tasks/BackgroundService.cs
This commit is contained in:
@@ -28,13 +28,6 @@ namespace Orchard.Tests.Environment {
|
||||
container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.Current())
|
||||
.Returns(() => _httpContextCurrent);
|
||||
|
||||
container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.CreateContext(It.IsAny<ILifetimeScope>()))
|
||||
.Returns(() => new StubHttpContext());
|
||||
|
||||
container.Mock<IWorkContextEvents>()
|
||||
.Setup(x => x.Started());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@@ -56,11 +56,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
|
||||
_container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.Current())
|
||||
.Returns(httpContext);
|
||||
|
||||
_container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.CreateContext(It.IsAny<ILifetimeScope>()))
|
||||
.Returns(httpContext);
|
||||
.Returns(default(HttpContextBase));
|
||||
|
||||
var factory = _container.Resolve<IShellContextFactory>();
|
||||
|
||||
|
@@ -43,10 +43,6 @@ namespace Orchard.Tests.Environment.State {
|
||||
_container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x=>x.Current())
|
||||
.Returns(httpContext);
|
||||
_container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.CreateContext(It.IsAny<ILifetimeScope>()))
|
||||
.Returns(httpContext);
|
||||
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System.Web;
|
||||
using Autofac;
|
||||
using Orchard.Mvc;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
@@ -17,10 +16,6 @@ namespace Orchard.Tests.Stubs {
|
||||
return _httpContext;
|
||||
}
|
||||
|
||||
public HttpContextBase CreateContext(ILifetimeScope lifetimeScope) {
|
||||
return _httpContext;
|
||||
}
|
||||
|
||||
public void Set(HttpContextBase httpContext) {
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
@@ -23,10 +23,6 @@ namespace Orchard.Tests.Tasks {
|
||||
.Setup(x => x.Current())
|
||||
.Returns(() => null);
|
||||
|
||||
container.Mock<IHttpContextAccessor>()
|
||||
.Setup(x => x.CreateContext(It.IsAny<ILifetimeScope>()))
|
||||
.Returns(() => new StubHttpContext());
|
||||
|
||||
container.Mock<IWorkContextEvents>()
|
||||
.Setup(x => x.Started());
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Data.Migration;
|
||||
|
||||
namespace Orchard.Autoroute {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
|
||||
public int Create() {
|
||||
SchemaBuilder.CreateTable("AutoroutePartRecord",
|
||||
table => table
|
||||
|
@@ -16,7 +16,6 @@ namespace Orchard.Layouts.Handlers {
|
||||
private readonly IContentPartDisplay _contentPartDisplay;
|
||||
private readonly IShapeDisplay _shapeDisplay;
|
||||
private readonly ILayoutSerializer _serializer;
|
||||
private readonly IStaticHttpContextScopeFactory _staticHttpContextScopeFactory;
|
||||
private readonly IAliasService _aliasService;
|
||||
|
||||
public LayoutPartHandler(
|
||||
@@ -26,7 +25,6 @@ namespace Orchard.Layouts.Handlers {
|
||||
IContentPartDisplay contentPartDisplay,
|
||||
IShapeDisplay shapeDisplay,
|
||||
ILayoutSerializer serializer,
|
||||
IStaticHttpContextScopeFactory staticHttpContextScopeFactory,
|
||||
IAliasService aliasService) {
|
||||
|
||||
_layoutManager = layoutManager;
|
||||
@@ -34,7 +32,6 @@ namespace Orchard.Layouts.Handlers {
|
||||
_contentPartDisplay = contentPartDisplay;
|
||||
_shapeDisplay = shapeDisplay;
|
||||
_serializer = serializer;
|
||||
_staticHttpContextScopeFactory = staticHttpContextScopeFactory;
|
||||
_aliasService = aliasService;
|
||||
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
@@ -44,22 +41,13 @@ namespace Orchard.Layouts.Handlers {
|
||||
|
||||
private void IndexLayout(IndexContentContext context, LayoutPart part) {
|
||||
var layoutShape = _contentPartDisplay.BuildDisplay(part);
|
||||
var layoutHtml = RenderShape(layoutShape);
|
||||
var layoutHtml = _shapeDisplay.Display(layoutShape);
|
||||
|
||||
context.DocumentIndex
|
||||
.Add("body", layoutHtml).RemoveTags().Analyze()
|
||||
.Add("format", "html").Store();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method of rendering is safe even in background tasks.
|
||||
/// </summary>
|
||||
private string RenderShape(dynamic shape) {
|
||||
using (_staticHttpContextScopeFactory.CreateStaticScope()) {
|
||||
return _shapeDisplay.Display(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTemplateClients(PublishContentContext context, LayoutPart part) {
|
||||
UpdateTemplateClients(part);
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI;
|
||||
using System.Web.WebPages;
|
||||
@@ -14,6 +15,7 @@ namespace Orchard.Templates.Services {
|
||||
[OrchardFeature("Orchard.Templates.Razor")]
|
||||
public class RazorTemplateProcessor : TemplateProcessorImpl {
|
||||
private readonly IRazorCompiler _compiler;
|
||||
private readonly HttpContextBase _httpContextBase;
|
||||
private readonly IWorkContextAccessor _wca;
|
||||
|
||||
public override string Type {
|
||||
@@ -22,9 +24,11 @@ namespace Orchard.Templates.Services {
|
||||
|
||||
public RazorTemplateProcessor(
|
||||
IRazorCompiler compiler,
|
||||
HttpContextBase httpContextBase,
|
||||
IWorkContextAccessor wca) {
|
||||
|
||||
_compiler = compiler;
|
||||
_httpContextBase = httpContextBase;
|
||||
_wca = wca;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -37,7 +41,7 @@ namespace Orchard.Templates.Services {
|
||||
|
||||
public override string Process(string template, string name, DisplayContext context = null, dynamic model = null) {
|
||||
if (String.IsNullOrEmpty(template))
|
||||
return String.Empty;
|
||||
return string.Empty;
|
||||
|
||||
var compiledTemplate = _compiler.CompileRazor(template, name, new Dictionary<string, object>());
|
||||
var result = ActivateAndRenderTemplate(compiledTemplate, context, null, model);
|
||||
@@ -69,10 +73,9 @@ namespace Orchard.Templates.Services {
|
||||
// Setup a fake view context in order to support razor syntax inside of HTML attributes,
|
||||
// for instance: <a href="@WorkContext.CurrentSite.BaseUrl">Homepage</a>.
|
||||
var viewData = new ViewDataDictionary(model);
|
||||
var httpContext = _wca.GetContext().HttpContext;
|
||||
obj.ViewContext = new ViewContext(
|
||||
new ControllerContext(
|
||||
httpContext.Request.RequestContext,
|
||||
_httpContextBase.Request.RequestContext,
|
||||
new StubController()),
|
||||
new StubView(),
|
||||
viewData,
|
||||
@@ -80,7 +83,7 @@ namespace Orchard.Templates.Services {
|
||||
htmlWriter);
|
||||
|
||||
obj.ViewData = viewData;
|
||||
obj.WebPageContext = new WebPageContext(httpContext, obj as WebPageRenderingBase, model);
|
||||
obj.WebPageContext = new WebPageContext(_httpContextBase, obj as WebPageRenderingBase, model);
|
||||
obj.WorkContext = _wca.GetContext();
|
||||
}
|
||||
|
||||
|
@@ -179,8 +179,8 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
|
||||
private ControllerContext CreateControllerContext() {
|
||||
var controller = new StubController();
|
||||
var httpContext = _workContextAccessor.GetContext().HttpContext;
|
||||
var requestContext = httpContext.Request.RequestContext;
|
||||
var httpContext = _workContextAccessor.GetContext().Resolve<HttpContextBase>();
|
||||
var requestContext = _workContextAccessor.GetContext().Resolve<RequestContext>();
|
||||
var routeData = requestContext.RouteData;
|
||||
|
||||
routeData.DataTokens["IWorkContextAccessor"] = _workContextAccessor;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
@@ -8,24 +10,28 @@ namespace Orchard.DisplayManagement {
|
||||
public class ShapeDisplay : IShapeDisplay {
|
||||
private readonly IDisplayHelperFactory _displayHelperFactory;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly HttpContextBase _httpContextBase;
|
||||
private readonly RequestContext _requestContext;
|
||||
|
||||
public ShapeDisplay(
|
||||
IDisplayHelperFactory displayHelperFactory,
|
||||
IWorkContextAccessor workContextAccessor) {
|
||||
IDisplayHelperFactory displayHelperFactory,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
HttpContextBase httpContextBase,
|
||||
RequestContext requestContext) {
|
||||
_displayHelperFactory = displayHelperFactory;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_httpContextBase = httpContextBase;
|
||||
_requestContext = requestContext;
|
||||
}
|
||||
|
||||
public string Display(Shape shape) {
|
||||
return Display((object)shape);
|
||||
return Display((object) shape);
|
||||
}
|
||||
|
||||
public string Display(object shape) {
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
var httpContext = workContext.HttpContext;
|
||||
var viewContext = new ViewContext {
|
||||
HttpContext = httpContext,
|
||||
RequestContext = httpContext.Request.RequestContext
|
||||
HttpContext = _httpContextBase,
|
||||
RequestContext = _requestContext
|
||||
};
|
||||
viewContext.RouteData.DataTokens["IWorkContextAccessor"] = _workContextAccessor;
|
||||
var display = _displayHelperFactory.CreateHelper(viewContext, new ViewDataContainer());
|
||||
|
@@ -63,7 +63,7 @@ namespace Orchard.Environment {
|
||||
builder.RegisterType<AppDomainAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
|
||||
builder.RegisterType<GacAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
|
||||
builder.RegisterType<OrchardFrameworkAssemblyNameResolver>().As<IAssemblyNameResolver>().SingleInstance();
|
||||
builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
|
||||
builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().InstancePerDependency();
|
||||
builder.RegisterType<ViewsBackgroundCompilation>().As<IViewsBackgroundCompilation>().SingleInstance();
|
||||
builder.RegisterType<DefaultExceptionPolicy>().As<IExceptionPolicy>().SingleInstance();
|
||||
builder.RegisterType<DefaultCriticalErrorProvider>().As<ICriticalErrorProvider>().SingleInstance();
|
||||
|
@@ -60,14 +60,11 @@ namespace Orchard.Environment {
|
||||
return CreateWorkContextScope(httpContext);
|
||||
|
||||
var workLifetime = _lifetimeScope.BeginLifetimeScope("work");
|
||||
httpContext = _httpContextAccessor.CreateContext(workLifetime);
|
||||
workLifetime.Resolve<WorkContextProperty<HttpContextBase>>().Value = httpContext;
|
||||
|
||||
var events = workLifetime.Resolve<IEnumerable<IWorkContextEvents>>();
|
||||
events.Invoke(e => e.Started(), NullLogger.Instance);
|
||||
|
||||
return new ThreadStaticScopeImplementation(
|
||||
httpContext,
|
||||
events,
|
||||
workLifetime,
|
||||
EnsureThreadStaticContexts(),
|
||||
@@ -116,9 +113,8 @@ namespace Orchard.Environment {
|
||||
readonly WorkContext _workContext;
|
||||
readonly Action _disposer;
|
||||
|
||||
public ThreadStaticScopeImplementation(HttpContextBase httpContext, IEnumerable<IWorkContextEvents> events, ILifetimeScope lifetimeScope, ConcurrentDictionary<object, WorkContext> contexts, object workContextKey) {
|
||||
public ThreadStaticScopeImplementation(IEnumerable<IWorkContextEvents> events, ILifetimeScope lifetimeScope, ConcurrentDictionary<object, WorkContext> contexts, object workContextKey) {
|
||||
_workContext = lifetimeScope.Resolve<WorkContext>();
|
||||
httpContext.Items[workContextKey] = _workContext;
|
||||
contexts.AddOrUpdate(workContextKey, _workContext, (a, b) => _workContext);
|
||||
|
||||
_disposer = () => {
|
||||
@@ -127,11 +123,6 @@ namespace Orchard.Environment {
|
||||
WorkContext removedContext;
|
||||
contexts.TryRemove(workContextKey, out removedContext);
|
||||
lifetimeScope.Dispose();
|
||||
|
||||
var staticHttpContext = httpContext as IDisposable;
|
||||
|
||||
if(staticHttpContext != null)
|
||||
staticHttpContext.Dispose();
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard {
|
||||
/// <summary>
|
||||
/// A factory class that creates an <see cref="StaticHttpContextScope"/> instance and initializes the HttpContext.Current property with that instance until the scope is disposed of.
|
||||
/// This is useful when rendering views from a background thread, as some Html Helpers access HttpContext.Current directly, thus preventing a NullReferenceException.
|
||||
/// </summary>
|
||||
public interface IStaticHttpContextScopeFactory : IDependency {
|
||||
/// <summary>
|
||||
/// Creates a disposable static HttpContext scope. This is safe to use even if there is an actual HttpContext.Current instance.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IDisposable CreateStaticScope();
|
||||
}
|
||||
}
|
9
src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs
Normal file
9
src/Orchard/Mvc/Extensions/HttpContextBaseExtensions.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard.Mvc.Extensions {
|
||||
public static class HttpContextExtensions {
|
||||
public static bool IsBackgroundContext(this HttpContextBase httpContext) {
|
||||
return httpContext == null || httpContext is MvcModule.HttpContextPlaceholder;
|
||||
}
|
||||
|
||||
public static bool IsBackgroundContext(this HttpContext httpContext) {
|
||||
return httpContext == null || httpContext.Items.Contains(StaticHttpContextScopeFactory.IsBackgroundHttpContextKey);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,40 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Web;
|
||||
using Autofac;
|
||||
using Orchard.Mvc.Extensions;
|
||||
using Orchard.Settings;
|
||||
|
||||
namespace Orchard.Mvc {
|
||||
public class HttpContextAccessor : IHttpContextAccessor {
|
||||
readonly object _contextKey = new object();
|
||||
|
||||
[ThreadStatic]
|
||||
static ConcurrentDictionary<object, HttpContextBase> _threadStaticContexts;
|
||||
private HttpContextBase _httpContext;
|
||||
|
||||
public HttpContextBase Current() {
|
||||
if (!HttpContext.Current.IsBackgroundContext())
|
||||
return new HttpContextWrapper(HttpContext.Current);
|
||||
|
||||
return GetContext();
|
||||
var httpContext = GetStaticProperty();
|
||||
return !IsBackgroundHttpContext(httpContext) ? new HttpContextWrapper(httpContext) : _httpContext;
|
||||
}
|
||||
|
||||
public HttpContextBase CreateContext(ILifetimeScope lifetimeScope) {
|
||||
return new MvcModule.HttpContextPlaceholder(_threadStaticContexts, _contextKey, () => {
|
||||
var baseUrl = lifetimeScope.Resolve<ISiteService>().GetSiteSettings().BaseUrl;
|
||||
return !String.IsNullOrEmpty(baseUrl) ? baseUrl : "http://localhost"; // Return a valid URL always.
|
||||
});
|
||||
public void Set(HttpContextBase httpContext) {
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
private HttpContextBase GetContext() {
|
||||
HttpContextBase context;
|
||||
return ThreadStaticContexts.TryGetValue(_contextKey, out context) ? context : null;
|
||||
private static bool IsBackgroundHttpContext(HttpContext httpContext) {
|
||||
return httpContext == null || httpContext.Items.Contains(BackgroundHttpContextFactory.IsBackgroundHttpContextKey);
|
||||
}
|
||||
|
||||
static ConcurrentDictionary<object, HttpContextBase> ThreadStaticContexts {
|
||||
get {
|
||||
return _threadStaticContexts ?? (_threadStaticContexts = new ConcurrentDictionary<object, HttpContextBase>());
|
||||
private static HttpContext GetStaticProperty() {
|
||||
var httpContext = HttpContext.Current;
|
||||
if (httpContext == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// The "Request" property throws at application startup on IIS integrated pipeline mode.
|
||||
if (httpContext.Request == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
return null;
|
||||
}
|
||||
return httpContext;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +1,8 @@
|
||||
using System.Web;
|
||||
using Autofac;
|
||||
|
||||
namespace Orchard.Mvc {
|
||||
public interface IHttpContextAccessor {
|
||||
HttpContextBase Current();
|
||||
HttpContextBase CreateContext(ILifetimeScope lifetimeScope);
|
||||
void Set(HttpContextBase httpContext);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
@@ -10,7 +9,6 @@ using System.Web.Instrumentation;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Autofac;
|
||||
using Orchard.Mvc.Extensions;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Settings;
|
||||
|
||||
@@ -52,7 +50,7 @@ namespace Orchard.Mvc {
|
||||
// which requires activating the Site content item, which in turn requires a UrlHelper, which in turn requires a RequestContext,
|
||||
// thus preventing a StackOverflowException.
|
||||
var baseUrl = new Func<string>(() => siteService.GetSiteSettings().BaseUrl);
|
||||
var httpContextBase = context.Resolve<IHttpContextAccessor>().Current();
|
||||
var httpContextBase = new HttpContextPlaceholder(baseUrl);
|
||||
|
||||
if (httpContextBase == null) {
|
||||
context.Resolve<IWorkContextAccessor>().CreateWorkContextScope();
|
||||
@@ -66,7 +64,7 @@ namespace Orchard.Mvc {
|
||||
static RequestContext RequestContextFactory(IComponentContext context) {
|
||||
var httpContextAccessor = context.Resolve<IHttpContextAccessor>();
|
||||
var httpContext = httpContextAccessor.Current();
|
||||
if (!httpContext.IsBackgroundContext()) {
|
||||
if (httpContext != null) {
|
||||
|
||||
var mvcHandler = httpContext.Handler as MvcHandler;
|
||||
if (mvcHandler != null) {
|
||||
@@ -93,23 +91,16 @@ namespace Orchard.Mvc {
|
||||
/// <summary>
|
||||
/// Standin context for background tasks.
|
||||
/// </summary>
|
||||
public class HttpContextPlaceholder : HttpContextBase, IDisposable {
|
||||
public class HttpContextPlaceholder : HttpContextBase {
|
||||
private readonly Lazy<string> _baseUrl;
|
||||
private readonly IDictionary _items = new Dictionary<object, object>();
|
||||
readonly Action _disposer;
|
||||
|
||||
public HttpContextPlaceholder(ConcurrentDictionary<object, HttpContextBase> contexts, object contextKey, Func<string> baseUrl) {
|
||||
public HttpContextPlaceholder(Func<string> baseUrl) {
|
||||
_baseUrl = new Lazy<string>(baseUrl);
|
||||
contexts.AddOrUpdate(contextKey, this, (a, b) => this);
|
||||
|
||||
_disposer = () => {
|
||||
HttpContextBase removedContext;
|
||||
contexts.TryRemove(contextKey, out removedContext);
|
||||
};
|
||||
}
|
||||
|
||||
public override HttpRequestBase Request {
|
||||
get { return new HttpRequestPlaceholder(this, new Uri(_baseUrl.Value)); }
|
||||
get { return new HttpRequestPlaceholder(new Uri(_baseUrl.Value)); }
|
||||
}
|
||||
|
||||
public override IHttpHandler Handler { get; set; }
|
||||
@@ -118,10 +109,6 @@ namespace Orchard.Mvc {
|
||||
get { return new HttpResponsePlaceholder(); }
|
||||
}
|
||||
|
||||
public override HttpSessionStateBase Session {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public override IDictionary Items {
|
||||
get { return _items; }
|
||||
}
|
||||
@@ -137,10 +124,6 @@ namespace Orchard.Mvc {
|
||||
public override object GetService(Type serviceType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
_disposer();
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpResponsePlaceholder : HttpResponseBase {
|
||||
@@ -159,12 +142,9 @@ namespace Orchard.Mvc {
|
||||
/// standin context for background tasks.
|
||||
/// </summary>
|
||||
public class HttpRequestPlaceholder : HttpRequestBase {
|
||||
private readonly HttpContextBase _httpContext;
|
||||
private readonly Uri _uri;
|
||||
private RequestContext _requestContext;
|
||||
|
||||
public HttpRequestPlaceholder(HttpContextBase httpContext, Uri uri) {
|
||||
_httpContext = httpContext;
|
||||
public HttpRequestPlaceholder(Uri uri) {
|
||||
_uri = uri;
|
||||
}
|
||||
|
||||
@@ -223,7 +203,7 @@ namespace Orchard.Mvc {
|
||||
return new NameValueCollection {
|
||||
{ "SERVER_PORT", _uri.Port.ToString(CultureInfo.InvariantCulture) },
|
||||
{ "HTTP_HOST", _uri.Authority.ToString(CultureInfo.InvariantCulture) },
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -265,16 +245,6 @@ namespace Orchard.Mvc {
|
||||
return new HttpBrowserCapabilitiesPlaceholder();
|
||||
}
|
||||
}
|
||||
|
||||
public override RequestContext RequestContext {
|
||||
get {
|
||||
if (_requestContext == null) {
|
||||
_requestContext = new RequestContext(_httpContext, new RouteData());
|
||||
}
|
||||
return _requestContext;
|
||||
}
|
||||
set { _requestContext = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpBrowserCapabilitiesPlaceholder : HttpBrowserCapabilitiesBase {
|
||||
|
@@ -149,12 +149,11 @@
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackgroundHttpContextFactory.cs" />
|
||||
<Compile Include="Localization\Services\ILocalizationStreamParser.cs" />
|
||||
<Compile Include="Localization\Services\LocalizationStreamParser.cs" />
|
||||
<Compile Include="Security\ISslSettingsProvider.cs" />
|
||||
<Compile Include="Security\Providers\DefaultSslSettingsProvider.cs" />
|
||||
<Compile Include="StaticHttpContextScope.cs" />
|
||||
<Compile Include="StaticHttpContextScopeFactory.cs" />
|
||||
<Compile Include="Caching\DefaultCacheContextAccessor.cs" />
|
||||
<Compile Include="Caching\DefaultParallelCacheContext.cs" />
|
||||
<Compile Include="Caching\ICacheContextAccessor.cs" />
|
||||
@@ -323,7 +322,7 @@
|
||||
<Compile Include="Mvc\DataAnnotations\LocalizedModelValidatorProvider.cs" />
|
||||
<Compile Include="Mvc\DataAnnotations\LocalizedRequiredAttribute.cs" />
|
||||
<Compile Include="Mvc\Extensions\RouteExtension.cs" />
|
||||
<Compile Include="Mvc\Extensions\HttpContextExtensions.cs" />
|
||||
<Compile Include="Mvc\Extensions\HttpContextBaseExtensions.cs" />
|
||||
<Compile Include="Mvc\FormValueRequiredAttribute.cs" />
|
||||
<Compile Include="Mvc\HttpContextAccessor.cs" />
|
||||
<Compile Include="Mvc\HttpContextWorkContext.cs" />
|
||||
@@ -653,7 +652,7 @@
|
||||
<Compile Include="WebApi\Filters\OrchardApiActionFilterDispatcher.cs" />
|
||||
<Compile Include="WebApi\Routes\IHttpRouteProvider.cs" />
|
||||
<Compile Include="WebApi\Routes\StandardExtensionHttpRouteProvider.cs" />
|
||||
<Compile Include="IStaticHttpContextScopeFactory.cs" />
|
||||
<Compile Include="IBackgroundHttpContextFactory.cs" />
|
||||
<Compile Include="WorkContextExtensions.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\Razor\RazorCompilationEventsShim.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\Razor\RazorViewEngineProvider.cs" />
|
||||
@@ -1029,4 +1028,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard {
|
||||
public class StaticHttpContextScope : IDisposable {
|
||||
private readonly HttpContext _previousHttpContext;
|
||||
|
||||
public StaticHttpContextScope(HttpContext stub) {
|
||||
_previousHttpContext = HttpContext.Current;
|
||||
HttpContext.Current = stub;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
HttpContext.Current = _previousHttpContext;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Orchard.Settings;
|
||||
|
||||
namespace Orchard {
|
||||
public class StaticHttpContextScopeFactory : IStaticHttpContextScopeFactory {
|
||||
private readonly Func<ISiteService> _siteService;
|
||||
public StaticHttpContextScopeFactory(Func<ISiteService> siteService) {
|
||||
_siteService = siteService;
|
||||
}
|
||||
|
||||
public const string IsBackgroundHttpContextKey = "IsBackgroundHttpContext";
|
||||
|
||||
public IDisposable CreateStaticScope() {
|
||||
// If there already is a current HttpContext, use that one as the stub.
|
||||
if(HttpContext.Current != null)
|
||||
return new StaticHttpContextScope(HttpContext.Current);
|
||||
|
||||
// We're in a background task (or some other static context like the console),
|
||||
// so create a stub context so that Html Helpers can still be executed when rendering shapes in background tasks
|
||||
// (sadly enought some Html Helpers access HttpContext.Current directly).
|
||||
var url = _siteService().GetSiteSettings().BaseUrl;
|
||||
var stub = new HttpContext(new HttpRequest("", url, ""), new HttpResponse(new StringWriter()));
|
||||
|
||||
stub.Items[IsBackgroundHttpContextKey] = true;
|
||||
|
||||
return new StaticHttpContextScope(stub);
|
||||
}
|
||||
}
|
||||
}
|
@@ -18,7 +18,8 @@ namespace Orchard.Tasks {
|
||||
public BackgroundService(
|
||||
IEnumerable<IBackgroundTask> tasks,
|
||||
ITransactionManager transactionManager,
|
||||
ShellSettings shellSettings) {
|
||||
ShellSettings shellSettings,
|
||||
IBackgroundHttpContextFactory backgroundHttpContextFactory) {
|
||||
|
||||
_tasks = tasks;
|
||||
_transactionManager = transactionManager;
|
||||
|
@@ -41,7 +41,7 @@ namespace Orchard.Tasks {
|
||||
}
|
||||
|
||||
void Elapsed(object sender, ElapsedEventArgs e) {
|
||||
// Current implementation disallows re-entrancy.
|
||||
// current implementation disallows re-entrancy
|
||||
if (!System.Threading.Monitor.TryEnter(_timer))
|
||||
return;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Orchard.Tasks {
|
||||
|
||||
public void DoWork() {
|
||||
using (var scope = _workContextAccessor.CreateWorkContextScope()) {
|
||||
// Resolve the manager and invoke it.
|
||||
// resolve the manager and invoke it
|
||||
var manager = scope.Resolve<IBackgroundService>();
|
||||
manager.Sweep();
|
||||
}
|
||||
|
Reference in New Issue
Block a user