mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-02 11:44:41 +08:00
#18793: Making session utilization an opt-in/opt-out feature
Work Item: 18793 --HG-- branch : 1.x
This commit is contained in:
@@ -6,8 +6,10 @@ using System.Web.Routing;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Tests.Stubs;
|
||||
@@ -36,6 +38,10 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
rootBuilder.RegisterModule(new WorkContextModule());
|
||||
rootBuilder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>().InstancePerMatchingLifetimeScope("shell");
|
||||
rootBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();
|
||||
rootBuilder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
||||
rootBuilder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||
rootBuilder.RegisterType<StubAsyncTokenProvider>().As<IAsyncTokenProvider>();
|
||||
rootBuilder.RegisterType<StubParallelCacheContext>().As<IParallelCacheContext>();
|
||||
|
||||
_rootContainer = rootBuilder.Build();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
public class StubHttpContext : HttpContextBase {
|
||||
@@ -24,6 +25,9 @@ namespace Orchard.Tests.Stubs {
|
||||
_hostHeader = hostHeader;
|
||||
}
|
||||
|
||||
public override void SetSessionStateBehavior(SessionStateBehavior sessionStateBehavior) {
|
||||
}
|
||||
|
||||
public override HttpRequestBase Request {
|
||||
get { return new StubHttpRequest(this); }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Name: Themes
|
||||
AntiForgery: enabled
|
||||
SessionState: required
|
||||
Author: The Orchard Team
|
||||
Website: http://orchardproject.net
|
||||
Version: 1.5
|
||||
|
||||
@@ -12,16 +12,22 @@ namespace Orchard.Themes.Preview {
|
||||
|
||||
public string GetPreviewTheme() {
|
||||
var httpContext = _httpContextAccessor.Current();
|
||||
return Convert.ToString(httpContext.Session[PreviewThemeKey]);
|
||||
if (httpContext.Session != null) {
|
||||
return Convert.ToString(httpContext.Session[PreviewThemeKey]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetPreviewTheme(string themeName) {
|
||||
var httpContext = _httpContextAccessor.Current();
|
||||
if (string.IsNullOrEmpty(themeName)) {
|
||||
httpContext.Session.Remove(PreviewThemeKey);
|
||||
}
|
||||
else {
|
||||
httpContext.Session[PreviewThemeKey] = themeName;
|
||||
if (httpContext.Session != null) {
|
||||
if (string.IsNullOrEmpty(themeName)) {
|
||||
httpContext.Session.Remove(PreviewThemeKey);
|
||||
}
|
||||
else {
|
||||
httpContext.Session[PreviewThemeKey] = themeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
private const string FeatureNameSection = "featurename";
|
||||
private const string PrioritySection = "priority";
|
||||
private const string FeaturesSection = "features";
|
||||
private const string SessionStateSection = "sessionstate";
|
||||
|
||||
private readonly ICacheManager _cacheManager;
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
@@ -116,7 +117,8 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
Tags = GetValue(manifest, TagsSection),
|
||||
AntiForgery = GetValue(manifest, AntiForgerySection),
|
||||
Zones = GetValue(manifest, ZonesSection),
|
||||
BaseTheme = GetValue(manifest, BaseThemeSection)
|
||||
BaseTheme = GetValue(manifest, BaseThemeSection),
|
||||
SessionState = GetValue(manifest, SessionStateSection)
|
||||
};
|
||||
extensionDescriptor.Features = GetFeaturesForExtension(manifest, extensionDescriptor);
|
||||
|
||||
@@ -202,6 +204,9 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
case PrioritySection:
|
||||
manifest.Add(PrioritySection, field[1]);
|
||||
break;
|
||||
case SessionStateSection:
|
||||
manifest.Add(SessionStateSection, field[1]);
|
||||
break;
|
||||
case FeaturesSection:
|
||||
manifest.Add(FeaturesSection, reader.ReadToEnd());
|
||||
break;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Orchard.Environment.Extensions.Models {
|
||||
public string AntiForgery { get; set; }
|
||||
public string Zones { get; set; }
|
||||
public string BaseTheme { get; set; }
|
||||
public string SessionState { get; set; }
|
||||
|
||||
public IEnumerable<FeatureDescriptor> Features { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
|
||||
namespace Orchard.Mvc.Routes {
|
||||
public class RouteDescriptor {
|
||||
public string Name { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public RouteBase Route { get; set; }
|
||||
public SessionStateBehavior SessionState { get; set; }
|
||||
}
|
||||
|
||||
public class HttpRouteDescriptor : RouteDescriptor {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
|
||||
namespace Orchard.Mvc.Routes {
|
||||
public class RoutePublisher : IRoutePublisher {
|
||||
@@ -11,16 +14,19 @@ namespace Orchard.Mvc.Routes {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRunningShellTable _runningShellTable;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
|
||||
public RoutePublisher(
|
||||
RouteCollection routeCollection,
|
||||
ShellSettings shellSettings,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IRunningShellTable runningShellTable) {
|
||||
IRunningShellTable runningShellTable,
|
||||
IExtensionManager extensionManager) {
|
||||
_routeCollection = routeCollection;
|
||||
_shellSettings = shellSettings;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_runningShellTable = runningShellTable;
|
||||
_extensionManager = extensionManager;
|
||||
}
|
||||
|
||||
public void Publish(IEnumerable<RouteDescriptor> routes) {
|
||||
@@ -58,10 +64,35 @@ namespace Orchard.Mvc.Routes {
|
||||
|
||||
// new routes are added
|
||||
foreach (var routeDescriptor in routesArray) {
|
||||
var shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _workContextAccessor, _runningShellTable){IsHttpRoute = routeDescriptor is HttpRouteDescriptor};
|
||||
// Loading session state information.
|
||||
var defaultSessionState = SessionStateBehavior.Default;
|
||||
|
||||
if(routeDescriptor.Route is Route) {
|
||||
object extensionId;
|
||||
var routeCasted = routeDescriptor.Route as Route;
|
||||
if(routeCasted != null && routeCasted.Constraints != null && routeCasted.Constraints.TryGetValue("area", out extensionId)) {
|
||||
var extensionDescriptor = _extensionManager.GetExtension(extensionId.ToString());
|
||||
if(extensionDescriptor != null) {
|
||||
// if session state is not define explicitly, use the one define for the extension
|
||||
if(routeDescriptor.SessionState == SessionStateBehavior.Default) {
|
||||
Enum.TryParse(extensionDescriptor.SessionState, true /*ignoreCase*/, out defaultSessionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Route-level setting overrides module-level setting (from manifest).
|
||||
var sessionStateBehavior = routeDescriptor.SessionState == SessionStateBehavior.Default ? defaultSessionState : routeDescriptor.SessionState ;
|
||||
|
||||
var shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _workContextAccessor, _runningShellTable) {
|
||||
IsHttpRoute = routeDescriptor is HttpRouteDescriptor,
|
||||
SessionState = sessionStateBehavior
|
||||
};
|
||||
_routeCollection.Add(routeDescriptor.Name, shellRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using System.Web.Http.WebHost;
|
||||
using System.Web.Http.WebHost.Routing;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
@@ -30,6 +28,8 @@ namespace Orchard.Mvc.Routes {
|
||||
Area = route.GetAreaName();
|
||||
}
|
||||
|
||||
public SessionStateBehavior SessionState { get; set; }
|
||||
|
||||
public string ShellSettingsName { get { return _shellSettings.Name; } }
|
||||
public string Area { get; private set; }
|
||||
public bool IsHttpRoute { get; set; }
|
||||
@@ -50,8 +50,11 @@ namespace Orchard.Mvc.Routes {
|
||||
if (routeData == null)
|
||||
return null;
|
||||
|
||||
// push provided session state behavior to underlying MvcHandler
|
||||
effectiveHttpContext.SetSessionStateBehavior(SessionState);
|
||||
|
||||
// otherwise wrap handler and return it
|
||||
routeData.RouteHandler = new RouteHandler(_workContextAccessor, routeData.RouteHandler);
|
||||
routeData.RouteHandler = new RouteHandler(_workContextAccessor, routeData.RouteHandler, SessionState);
|
||||
routeData.DataTokens["IWorkContextAccessor"] = _workContextAccessor;
|
||||
|
||||
if (IsHttpRoute) {
|
||||
@@ -87,14 +90,17 @@ namespace Orchard.Mvc.Routes {
|
||||
class RouteHandler : IRouteHandler {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRouteHandler _routeHandler;
|
||||
private readonly SessionStateBehavior _sessionStateBehavior;
|
||||
|
||||
public RouteHandler(IWorkContextAccessor workContextAccessor, IRouteHandler routeHandler) {
|
||||
public RouteHandler(IWorkContextAccessor workContextAccessor, IRouteHandler routeHandler, SessionStateBehavior sessionStateBehavior) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_routeHandler = routeHandler;
|
||||
_sessionStateBehavior = sessionStateBehavior;
|
||||
}
|
||||
|
||||
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
|
||||
var httpHandler = _routeHandler.GetHttpHandler(requestContext);
|
||||
requestContext.HttpContext.SetSessionStateBehavior(_sessionStateBehavior);
|
||||
|
||||
if (httpHandler is IHttpAsyncHandler) {
|
||||
return new HttpAsyncHandler(_workContextAccessor, (IHttpAsyncHandler)httpHandler);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
|
||||
namespace Orchard.Mvc.Routes {
|
||||
@@ -15,14 +17,19 @@ namespace Orchard.Mvc.Routes {
|
||||
public IEnumerable<RouteDescriptor> GetRoutes() {
|
||||
var displayPathsPerArea = _blueprint.Controllers.GroupBy(
|
||||
x => x.AreaName,
|
||||
x => x.Feature.Descriptor.Extension.Path);
|
||||
x => x.Feature.Descriptor.Extension);
|
||||
|
||||
foreach (var item in displayPathsPerArea) {
|
||||
var areaName = item.Key;
|
||||
var displayPath = item.Distinct().Single();
|
||||
var extensionDescriptor = item.Distinct().Single();
|
||||
var displayPath = extensionDescriptor.Path;
|
||||
SessionStateBehavior defaultSessionState;
|
||||
Enum.TryParse(extensionDescriptor.SessionState, true /*ignoreCase*/, out defaultSessionState);
|
||||
|
||||
|
||||
yield return new RouteDescriptor {
|
||||
Priority = -10,
|
||||
SessionState = defaultSessionState,
|
||||
Route = new Route(
|
||||
"Admin/" + displayPath + "/{action}/{id}",
|
||||
new RouteValueDictionary {
|
||||
@@ -37,8 +44,10 @@ namespace Orchard.Mvc.Routes {
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
};
|
||||
|
||||
yield return new RouteDescriptor {
|
||||
Priority = -10,
|
||||
SessionState = defaultSessionState == SessionStateBehavior.Default ? SessionStateBehavior.Disabled : defaultSessionState, // sessions are disabled by default on front-end
|
||||
Route = new Route(
|
||||
displayPath + "/{controller}/{action}/{id}",
|
||||
new RouteValueDictionary {
|
||||
@@ -60,6 +69,5 @@ namespace Orchard.Mvc.Routes {
|
||||
foreach (var routeDescriptor in GetRoutes())
|
||||
routes.Add(routeDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
using Orchard.Mvc.Wrappers;
|
||||
|
||||
namespace Orchard.Mvc.Routes {
|
||||
@@ -16,6 +17,11 @@ namespace Orchard.Mvc.Routes {
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetSessionStateBehavior(SessionStateBehavior sessionStateBehavior)
|
||||
{
|
||||
_httpContextBase.SetSessionStateBehavior(sessionStateBehavior);
|
||||
}
|
||||
|
||||
class AdjustedRequest : HttpRequestBaseWrapper {
|
||||
private readonly UrlPrefix _prefix;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user