From 640b2c0ee04df03feab8d3cf12ff201f478470ed Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 16 Feb 2016 11:17:47 +0100 Subject: [PATCH] Moves strings to constants, adds ControllerContextExtensions to get the UmbracoContext from the hierarchy of ControllerContext's, changes RenderModelBinder to use this method to get the UmbracoContext, changes UmbracoViewPageOfTModel to use this method to get the UmbracoContext, adds RouteDataExtensions to get the UmbracoContext from routedata, adds extension methods on the HttpContext to get the UmbracoContext from it. --- src/Umbraco.Core/Constants-Web.cs | 6 +++ .../Mvc/SurfaceControllerTests.cs | 2 +- src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs | 2 +- .../Macros/PartialViewMacroEngine.cs | 2 +- .../Mvc/AreaRegistrationExtensions.cs | 2 +- .../Mvc/ControllerContextExtensions.cs | 50 +++++++++++++++++++ src/Umbraco.Web/Mvc/ControllerExtensions.cs | 18 +------ src/Umbraco.Web/Mvc/RenderModelBinder.cs | 16 +++--- src/Umbraco.Web/Mvc/RenderMvcController.cs | 4 +- src/Umbraco.Web/Mvc/RenderRouteHandler.cs | 10 ++-- src/Umbraco.Web/Mvc/RenderViewEngine.cs | 2 +- .../Mvc/RouteValueDictionaryExtensions.cs | 2 +- src/Umbraco.Web/Mvc/SurfaceController.cs | 4 +- .../Mvc/SurfaceControllerFactory.cs | 2 +- src/Umbraco.Web/Mvc/UmbracoPageResult.cs | 4 +- .../Mvc/UmbracoViewPageOfTModel.cs | 33 ++++-------- .../Mvc/UmbracoVirtualNodeRouteHandler.cs | 15 +++--- src/Umbraco.Web/RouteDataExtensions.cs | 28 +++++++++++ .../Routing/CustomRouteUrlProvider.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 + src/Umbraco.Web/UmbracoContext.cs | 2 +- src/Umbraco.Web/UmbracoContextExtensions.cs | 34 +++++++++++++ src/Umbraco.Web/WebBootManager.cs | 4 +- 23 files changed, 173 insertions(+), 73 deletions(-) create mode 100644 src/Umbraco.Web/Mvc/ControllerContextExtensions.cs create mode 100644 src/Umbraco.Web/RouteDataExtensions.cs diff --git a/src/Umbraco.Core/Constants-Web.cs b/src/Umbraco.Core/Constants-Web.cs index 60fba0ae40..f596820506 100644 --- a/src/Umbraco.Core/Constants-Web.cs +++ b/src/Umbraco.Core/Constants-Web.cs @@ -10,6 +10,12 @@ namespace Umbraco.Core /// public static class Web { + public const string UmbracoContextDataToken = "umbraco-context"; + public const string UmbracoDataToken = "umbraco"; + public const string PublishedDocumentRequestDataToken = "umbraco-doc-request"; + public const string CustomRouteDataToken = "umbraco-custom-route"; + public const string UmbracoRouteDefinitionDataToken = "umbraco-route-def"; + /// /// The preview cookie name /// diff --git a/src/Umbraco.Tests/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Mvc/SurfaceControllerTests.cs index 0286a5bd0f..29a76b29d2 100644 --- a/src/Umbraco.Tests/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Mvc/SurfaceControllerTests.cs @@ -165,7 +165,7 @@ namespace Umbraco.Tests.Mvc }; var routeData = new RouteData(); - routeData.DataTokens.Add("umbraco-route-def", routeDefinition); + routeData.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken, routeDefinition); var ctrl = new TestSurfaceController(umbCtx, new UmbracoHelper()); ctrl.ControllerContext = new ControllerContext(contextBase, routeData, ctrl); diff --git a/src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs index ed6cc9b4eb..5f80909da9 100644 --- a/src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs @@ -445,7 +445,7 @@ namespace Umbraco.Tests.Mvc var context = new ViewContext(); context.RouteData = new RouteData(); - context.RouteData.DataTokens.Add("umbraco-context", umbracoContext); + context.RouteData.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoContextDataToken, umbracoContext); return context; } diff --git a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs index b4171add35..10d105883f 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs @@ -124,7 +124,7 @@ namespace Umbraco.Web.Macros var routeVals = new RouteData(); routeVals.Values.Add("controller", "PartialViewMacro"); routeVals.Values.Add("action", "Index"); - routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage + routeVals.DataTokens.Add(Umbraco.Core.Constants.Web.UmbracoContextDataToken, umbCtx); //required for UmbracoViewPage //lets render this controller as a child action var viewContext = new ViewContext {ViewData = new ViewDataDictionary()};; diff --git a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs index 2836c458fb..982286c24b 100644 --- a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs +++ b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs @@ -110,7 +110,7 @@ namespace Umbraco.Web.Mvc //match this area controllerPluginRoute.DataTokens.Add("area", area.AreaName); - controllerPluginRoute.DataTokens.Add("umbraco", umbracoTokenValue); //ensure the umbraco token is set + controllerPluginRoute.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, umbracoTokenValue); //ensure the umbraco token is set return controllerPluginRoute; } diff --git a/src/Umbraco.Web/Mvc/ControllerContextExtensions.cs b/src/Umbraco.Web/Mvc/ControllerContextExtensions.cs new file mode 100644 index 0000000000..c998ed931e --- /dev/null +++ b/src/Umbraco.Web/Mvc/ControllerContextExtensions.cs @@ -0,0 +1,50 @@ +using System.Web.Mvc; + +namespace Umbraco.Web.Mvc +{ + public static class ControllerContextExtensions + { + /// + /// Tries to get the Umbraco context from the whole ControllerContext hierarchy based on data tokens and if that fails + /// it will attempt to fallback to retrieving it from the HttpContext. + /// + /// + /// + public static UmbracoContext GetUmbracoContext(this ControllerContext controllerContext) + { + var umbCtx = controllerContext.RouteData.GetUmbracoContext(); + if (umbCtx != null) return umbCtx; + + if (controllerContext.ParentActionViewContext != null) + { + //recurse + return controllerContext.ParentActionViewContext.GetUmbracoContext(); + } + + //fallback to getting from HttpContext + return controllerContext.HttpContext.GetUmbracoContext(); + } + + /// + /// Find a data token in the whole ControllerContext hierarchy of execution + /// + /// + /// + /// + internal static object GetDataTokenInViewContextHierarchy(this ControllerContext controllerContext, string dataTokenName) + { + if (controllerContext.RouteData.DataTokens.ContainsKey(dataTokenName)) + { + return controllerContext.RouteData.DataTokens[dataTokenName]; + } + + if (controllerContext.ParentActionViewContext != null) + { + //recurse! + return controllerContext.ParentActionViewContext.GetDataTokenInViewContextHierarchy(dataTokenName); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/ControllerExtensions.cs b/src/Umbraco.Web/Mvc/ControllerExtensions.cs index c15520b57c..734e60e8f5 100644 --- a/src/Umbraco.Web/Mvc/ControllerExtensions.cs +++ b/src/Umbraco.Web/Mvc/ControllerExtensions.cs @@ -5,24 +5,8 @@ using System.Web.Mvc; namespace Umbraco.Web.Mvc { - internal static class ControllerExtensions + internal static class ControllerExtensions { - internal static object GetDataTokenInViewContextHierarchy(this ControllerContext controllerContext, string dataTokenName) - { - if (controllerContext.RouteData.DataTokens.ContainsKey(dataTokenName)) - { - return controllerContext.RouteData.DataTokens[dataTokenName]; - } - - if (controllerContext.ParentActionViewContext != null) - { - //recurse! - return controllerContext.ParentActionViewContext.GetDataTokenInViewContextHierarchy(dataTokenName); - } - - return null; - } - /// /// Return the controller name from the controller type /// diff --git a/src/Umbraco.Web/Mvc/RenderModelBinder.cs b/src/Umbraco.Web/Mvc/RenderModelBinder.cs index ed81959fbd..f8e7ee8a4e 100644 --- a/src/Umbraco.Web/Mvc/RenderModelBinder.cs +++ b/src/Umbraco.Web/Mvc/RenderModelBinder.cs @@ -19,15 +19,19 @@ namespace Umbraco.Web.Mvc public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object model; - if (controllerContext.RouteData.DataTokens.TryGetValue("umbraco", out model) == false) + if (controllerContext.RouteData.DataTokens.TryGetValue(Core.Constants.Web.UmbracoDataToken, out model) == false) return null; + //default culture var culture = CultureInfo.CurrentCulture; - // bind the model (use context culture as default, if available) - if (UmbracoContext.Current != null - && UmbracoContext.Current.PublishedContentRequest != null - && UmbracoContext.Current.PublishedContentRequest.Culture != null) - culture = UmbracoContext.Current.PublishedContentRequest.Culture; + + var umbracoContext = controllerContext.GetUmbracoContext() + ?? UmbracoContext.Current; + + if (umbracoContext != null && umbracoContext.PublishedContentRequest != null) + { + culture = umbracoContext.PublishedContentRequest.Culture; + } return BindModel(model, bindingContext.ModelType, culture); } diff --git a/src/Umbraco.Web/Mvc/RenderMvcController.cs b/src/Umbraco.Web/Mvc/RenderMvcController.cs index dd06b3ced1..f3886d8ce1 100644 --- a/src/Umbraco.Web/Mvc/RenderMvcController.cs +++ b/src/Umbraco.Web/Mvc/RenderMvcController.cs @@ -59,11 +59,11 @@ namespace Umbraco.Web.Mvc { if (_publishedContentRequest != null) return _publishedContentRequest; - if (RouteData.DataTokens.ContainsKey("umbraco-doc-request") == false) + if (RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken) == false) { throw new InvalidOperationException("DataTokens must contain an 'umbraco-doc-request' key with a PublishedContentRequest object"); } - _publishedContentRequest = (PublishedContentRequest)RouteData.DataTokens["umbraco-doc-request"]; + _publishedContentRequest = (PublishedContentRequest)RouteData.DataTokens[Core.Constants.Web.PublishedDocumentRequestDataToken]; return _publishedContentRequest; } } diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index bce3515c1b..d7ce36b4a4 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -97,9 +97,9 @@ namespace Umbraco.Web.Mvc internal void SetupRouteDataForRequest(RenderModel renderModel, RequestContext requestContext, PublishedContentRequest docRequest) { //put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine - requestContext.RouteData.DataTokens.Add("umbraco", renderModel); //required for the RenderModelBinder and view engine - requestContext.RouteData.DataTokens.Add("umbraco-doc-request", docRequest); //required for RenderMvcController - requestContext.RouteData.DataTokens.Add("umbraco-context", UmbracoContext); //required for UmbracoTemplatePage + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, renderModel); //required for the RenderModelBinder and view engine + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, docRequest); //required for RenderMvcController + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, UmbracoContext); //required for UmbracoTemplatePage } private void UpdateRouteDataForRequest(RenderModel renderModel, RequestContext requestContext) @@ -107,7 +107,7 @@ namespace Umbraco.Web.Mvc if (renderModel == null) throw new ArgumentNullException("renderModel"); if (requestContext == null) throw new ArgumentNullException("requestContext"); - requestContext.RouteData.DataTokens["umbraco"] = renderModel; + requestContext.RouteData.DataTokens[Core.Constants.Web.UmbracoDataToken] = renderModel; // the rest should not change -- it's only the published content that has changed } @@ -337,7 +337,7 @@ namespace Umbraco.Web.Mvc } //store the route definition - requestContext.RouteData.DataTokens["umbraco-route-def"] = def; + requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return def; } diff --git a/src/Umbraco.Web/Mvc/RenderViewEngine.cs b/src/Umbraco.Web/Mvc/RenderViewEngine.cs index ed7b941580..fdf61059e0 100644 --- a/src/Umbraco.Web/Mvc/RenderViewEngine.cs +++ b/src/Umbraco.Web/Mvc/RenderViewEngine.cs @@ -93,7 +93,7 @@ namespace Umbraco.Web.Mvc /// private bool ShouldFindView(ControllerContext controllerContext, bool isPartial) { - var umbracoToken = controllerContext.GetDataTokenInViewContextHierarchy("umbraco"); + var umbracoToken = controllerContext.GetDataTokenInViewContextHierarchy(Core.Constants.Web.UmbracoDataToken); //first check if we're rendering a partial view for the back office, or surface controller, etc... //anything that is not IUmbracoRenderModel as this should only pertain to Umbraco views. diff --git a/src/Umbraco.Web/Mvc/RouteValueDictionaryExtensions.cs b/src/Umbraco.Web/Mvc/RouteValueDictionaryExtensions.cs index 445441aafa..ceb4012a66 100644 --- a/src/Umbraco.Web/Mvc/RouteValueDictionaryExtensions.cs +++ b/src/Umbraco.Web/Mvc/RouteValueDictionaryExtensions.cs @@ -32,7 +32,7 @@ namespace Umbraco.Web.Mvc public static object GetRequiredObject(this RouteValueDictionary items, string key) { if (key == null) throw new ArgumentNullException("key"); - if (!items.Keys.Contains(key)) + if (items.Keys.Contains(key) == false) throw new ArgumentNullException("The " + key + " parameter was not found but is required"); return items[key]; } diff --git a/src/Umbraco.Web/Mvc/SurfaceController.cs b/src/Umbraco.Web/Mvc/SurfaceController.cs index 817ed97902..420573d745 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -185,9 +185,9 @@ namespace Umbraco.Web.Mvc while (currentContext != null) { var currentRouteData = currentContext.RouteData; - if (currentRouteData.DataTokens.ContainsKey("umbraco-route-def")) + if (currentRouteData.DataTokens.ContainsKey(Core.Constants.Web.UmbracoRouteDefinitionDataToken)) { - return Attempt.Succeed((RouteDefinition)currentRouteData.DataTokens["umbraco-route-def"]); + return Attempt.Succeed((RouteDefinition)currentRouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken]); } if (currentContext.IsChildAction) { diff --git a/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs b/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs index c82c59db65..8af018e833 100644 --- a/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs +++ b/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web.Mvc return false; //ensure there is an umbraco token set - var umbracoToken = request.RouteData.DataTokens["umbraco"]; + var umbracoToken = request.RouteData.DataTokens[Core.Constants.Web.UmbracoDataToken]; if (umbracoToken == null || string.IsNullOrWhiteSpace(umbracoToken.ToString())) return false; diff --git a/src/Umbraco.Web/Mvc/UmbracoPageResult.cs b/src/Umbraco.Web/Mvc/UmbracoPageResult.cs index f23515c1d9..da4cb198ac 100644 --- a/src/Umbraco.Web/Mvc/UmbracoPageResult.cs +++ b/src/Umbraco.Web/Mvc/UmbracoPageResult.cs @@ -34,7 +34,7 @@ namespace Umbraco.Web.Mvc ValidateRouteData(context.RouteData); - var routeDef = (RouteDefinition)context.RouteData.DataTokens["umbraco-route-def"]; + var routeDef = (RouteDefinition)context.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken]; //Special case, if it is webforms but we're posting to an MVC surface controller, then we // need to return the webforms result instead @@ -91,7 +91,7 @@ namespace Umbraco.Web.Mvc /// private static void ValidateRouteData(RouteData routeData) { - if (routeData.DataTokens.ContainsKey("umbraco-route-def") == false) + if (routeData.DataTokens.ContainsKey(Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken) == false) { throw new InvalidOperationException("Can only use " + typeof(UmbracoPageResult).Name + " in the context of an Http POST when using a SurfaceController form"); diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs index 562ef8542e..861b872275 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs @@ -27,24 +27,13 @@ namespace Umbraco.Web.Mvc get { //we should always try to return the context from the data tokens just in case its a custom context and not - //using the UmbracoContext.Current. - //we will fallback to the singleton if necessary. - if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) - { - return (UmbracoContext)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); - } - //next check if it is a child action and see if the parent has it set in data tokens - if (ViewContext.IsChildAction) - { - if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) - { - return (UmbracoContext)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); - } - } - - //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this - //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. - return UmbracoContext.Current; + //using the UmbracoContext.Current, we will fallback to the singleton if necessary. + var umbCtx = ViewContext.GetUmbracoContext() + //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this + //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. + ?? UmbracoContext.Current; + + return umbCtx; } } @@ -66,16 +55,16 @@ namespace Umbraco.Web.Mvc //we should always try to return the object from the data tokens just in case its a custom object and not //using the UmbracoContext.Current. //we will fallback to the singleton if necessary. - if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) + if (ViewContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken)) { - return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); + return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject(Core.Constants.Web.PublishedDocumentRequestDataToken); } //next check if it is a child action and see if the parent has it set in data tokens if (ViewContext.IsChildAction) { - if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) + if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken)) { - return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); + return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject(Core.Constants.Web.PublishedDocumentRequestDataToken); } } diff --git a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs index feb5b30ce2..5c948d2e0b 100644 --- a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; +using System.Web.Security; +using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Routing; @@ -19,7 +21,8 @@ namespace Umbraco.Web.Mvc if (found == null) return new NotFoundHandler(); umbracoContext.PublishedContentRequest = new PublishedContentRequest( - umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext) + umbracoContext.CleanedUmbracoUrl, umbracoContext.RoutingContext, + UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s)) { PublishedContent = found }; @@ -31,11 +34,11 @@ namespace Umbraco.Web.Mvc var renderModel = new RenderModel(umbracoContext.PublishedContentRequest.PublishedContent, umbracoContext.PublishedContentRequest.Culture); //assigns the required tokens to the request - requestContext.RouteData.DataTokens.Add("umbraco", renderModel); - requestContext.RouteData.DataTokens.Add("umbraco-doc-request", umbracoContext.PublishedContentRequest); - requestContext.RouteData.DataTokens.Add("umbraco-context", umbracoContext); + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, renderModel); + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.PublishedDocumentRequestDataToken, umbracoContext.PublishedContentRequest); + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext); //this is used just for a flag that this is an umbraco custom route - requestContext.RouteData.DataTokens.Add("umbraco-custom-route", true); + requestContext.RouteData.DataTokens.Add(Core.Constants.Web.CustomRouteDataToken, true); //Here we need to detect if a SurfaceController has posted var formInfo = RenderRouteHandler.GetFormInfo(requestContext); @@ -49,7 +52,7 @@ namespace Umbraco.Web.Mvc }; //set the special data token to the current route definition - requestContext.RouteData.DataTokens["umbraco-route-def"] = def; + requestContext.RouteData.DataTokens[Umbraco.Core.Constants.Web.UmbracoRouteDefinitionDataToken] = def; return RenderRouteHandler.HandlePostedValues(requestContext, formInfo); } diff --git a/src/Umbraco.Web/RouteDataExtensions.cs b/src/Umbraco.Web/RouteDataExtensions.cs new file mode 100644 index 0000000000..5d7f513ad6 --- /dev/null +++ b/src/Umbraco.Web/RouteDataExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Web.Routing; + +namespace Umbraco.Web +{ + public static class RouteDataExtensions + { + /// + /// Tries to get the Umbraco context from the DataTokens + /// + /// + /// + /// + /// This is useful when working on async threads since the UmbracoContext is not copied over explicitly + /// + public static UmbracoContext GetUmbracoContext(this RouteData routeData) + { + if (routeData == null) throw new ArgumentNullException("routeData"); + + if (routeData.DataTokens.ContainsKey(UmbracoContext.HttpContextItemName)) + { + var umbCtx = routeData.DataTokens[UmbracoContext.HttpContextItemName] as UmbracoContext; + return umbCtx; + } + return null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs index 2bb2903aa0..989cabe388 100644 --- a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs +++ b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs @@ -28,7 +28,7 @@ namespace Umbraco.Web.Routing if (umbracoContext.HttpContext.Request.RequestContext == null) return null; if (umbracoContext.HttpContext.Request.RequestContext.RouteData == null) return null; if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens == null) return null; - if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey("umbraco-custom-route") == false) return null; + if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Umbraco.Core.Constants.Web.CustomRouteDataToken) == false) return null; //ok so it's a custom route with published content assigned, check if the id being requested for is the same id as the assigned published content return id == umbracoContext.PublishedContentRequest.PublishedContent.Id ? umbracoContext.PublishedContentRequest.PublishedContent.Url diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 2c9542fe2d..e12afc0a65 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -341,6 +341,7 @@ + @@ -350,6 +351,7 @@ + diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 50788c4b2e..6bd325c275 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -21,7 +21,7 @@ namespace Umbraco.Web /// public class UmbracoContext : DisposableObject, IDisposeOnRequestEnd { - private const string HttpContextItemName = "Umbraco.Web.UmbracoContext"; + internal const string HttpContextItemName = "Umbraco.Web.UmbracoContext"; private static readonly object Locker = new object(); private bool _replacing; diff --git a/src/Umbraco.Web/UmbracoContextExtensions.cs b/src/Umbraco.Web/UmbracoContextExtensions.cs index ec85b4dad6..8cd38df6d1 100644 --- a/src/Umbraco.Web/UmbracoContextExtensions.cs +++ b/src/Umbraco.Web/UmbracoContextExtensions.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Web; +using Umbraco.Core; using Umbraco.Core.Events; namespace Umbraco.Web @@ -11,6 +13,38 @@ namespace Umbraco.Web /// public static class UmbracoContextExtensions { + /// + /// tries to get the Umbraco context from the HttpContext + /// + /// + /// + /// + /// This is useful when working on async threads since the UmbracoContext is not copied over explicitly + /// + public static UmbracoContext GetUmbracoContext(this HttpContext http) + { + return GetUmbracoContext(new HttpContextWrapper(http)); + } + + /// + /// tries to get the Umbraco context from the HttpContext + /// + /// + /// + /// + /// This is useful when working on async threads since the UmbracoContext is not copied over explicitly + /// + public static UmbracoContext GetUmbracoContext(this HttpContextBase http) + { + if (http == null) throw new ArgumentNullException("http"); + + if (http.Items.Contains(UmbracoContext.HttpContextItemName)) + { + var umbCtx = http.Items[UmbracoContext.HttpContextItemName] as UmbracoContext; + return umbCtx; + } + return null; + } /// /// If there are event messages in the current request this will return them , otherwise it will return null diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index c4252223f3..42ef78d96e 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -338,7 +338,7 @@ namespace Umbraco.Web { route.DataTokens = new RouteValueDictionary(); } - route.DataTokens.Add("umbraco", "api"); //ensure the umbraco token is set + route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set } private void RouteLocalSurfaceController(Type controller, string umbracoPath) @@ -349,7 +349,7 @@ namespace Umbraco.Web umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional }, new[] { meta.ControllerNamespace }); //look in this namespace to create the controller - route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set + route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); //ensure the umbraco token is set route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace! //make it use our custom/special SurfaceMvcHandler route.RouteHandler = new SurfaceRouteHandler();