diff --git a/src/Umbraco.Web/Editors/MacroController.cs b/src/Umbraco.Web/Editors/MacroController.cs
index aed6cec602..b0b2cb4bf2 100644
--- a/src/Umbraco.Web/Editors/MacroController.cs
+++ b/src/Umbraco.Web/Editors/MacroController.cs
@@ -4,21 +4,26 @@ using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
+using System.Web.SessionState;
using AutoMapper;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using umbraco;
+using Umbraco.Core;
namespace Umbraco.Web.Editors
{
///
/// API controller to deal with Macro data
///
+ ///
+ /// Note that this implements IRequiresSessionState which will enable HttpContext.Session - generally speaking we don't normally
+ /// enable this for webapi controllers, however since this controller is used to render macro content and macros can access
+ /// Session, we don't want it to throw null reference exceptions.
+ ///
[PluginController("UmbracoApi")]
- public class MacroController : UmbracoAuthorizedJsonController
+ public class MacroController : UmbracoAuthorizedJsonController, IRequiresSessionState
{
-
-
///
/// Gets the macro parameters to be filled in for a particular macro
///
@@ -124,6 +129,6 @@ namespace Umbraco.Web.Editors
"text/html");
return result;
}
-
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs
index 982286c24b..f1c27ffb96 100644
--- a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs
+++ b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs
@@ -3,8 +3,10 @@ using System.Collections.Generic;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
+using System.Web.SessionState;
using Umbraco.Core;
using Umbraco.Core.Configuration;
+using Umbraco.Web.WebApi;
namespace Umbraco.Web.Mvc
{
@@ -93,6 +95,13 @@ namespace Umbraco.Web.Mvc
}
//look in this namespace to create the controller
controllerPluginRoute.DataTokens.Add("Namespaces", new[] {controllerType.Namespace});
+
+ //Special case! Check if the controller type implements IRequiresSessionState and if so use our
+ //custom webapi session handler
+ if (typeof(IRequiresSessionState).IsAssignableFrom(controllerType))
+ {
+ controllerPluginRoute.RouteHandler = new SessionHttpControllerRouteHandler();
+ }
}
//Don't look anywhere else except this namespace!
@@ -100,9 +109,9 @@ namespace Umbraco.Web.Mvc
//constraints: only match controllers ending with 'controllerSuffixName' and only match this controller's ID for this route
if (controllerSuffixName.IsNullOrWhiteSpace() == false)
- {
- controllerPluginRoute.Constraints = new RouteValueDictionary(
- new Dictionary
+ {
+ controllerPluginRoute.Constraints = new RouteValueDictionary(
+ new Dictionary
{
{"controller", @"(\w+)" + controllerSuffixName}
});
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 31aa38b1bf..f756181cc4 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -956,6 +956,7 @@
+
diff --git a/src/Umbraco.Web/WebApi/SessionHttpControllerRouteHandler.cs b/src/Umbraco.Web/WebApi/SessionHttpControllerRouteHandler.cs
new file mode 100644
index 0000000000..d4d462c5f8
--- /dev/null
+++ b/src/Umbraco.Web/WebApi/SessionHttpControllerRouteHandler.cs
@@ -0,0 +1,31 @@
+using System.Web;
+using System.Web.Http.WebHost;
+using System.Web.Routing;
+using System.Web.SessionState;
+
+namespace Umbraco.Web.WebApi
+{
+ ///
+ /// A custom WebApi route handler that enables session on the HttpContext - use with caution!
+ ///
+ ///
+ /// WebApi controllers (and REST in general) shouldn't have session state enabled since it's stateless,
+ /// enabling session state puts additional locks on requests so only use this when absolutley needed
+ ///
+ internal class SessionHttpControllerRouteHandler : HttpControllerRouteHandler
+ {
+ protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
+ {
+ return new SessionHttpControllerHandler(requestContext.RouteData);
+ }
+
+ ///
+ /// A custom WebApi handler that enables session on the HttpContext
+ ///
+ private class SessionHttpControllerHandler : HttpControllerHandler, IRequiresSessionState
+ {
+ public SessionHttpControllerHandler(RouteData routeData) : base(routeData)
+ { }
+ }
+ }
+}
\ No newline at end of file