diff --git a/src/Umbraco.Web/Mvc/RedirectToUmbracoUrlResult.cs b/src/Umbraco.Web/Mvc/RedirectToUmbracoUrlResult.cs index fc472c0255..342a22c829 100644 --- a/src/Umbraco.Web/Mvc/RedirectToUmbracoUrlResult.cs +++ b/src/Umbraco.Web/Mvc/RedirectToUmbracoUrlResult.cs @@ -4,12 +4,12 @@ using System.Web.Mvc; namespace Umbraco.Web.Mvc { /// - /// Redirects to the current URL rendering an Umbraco page + /// Redirects to the current URL rendering an Umbraco page including it's query strings /// /// - /// this is useful if you need to redirect + /// This is useful if you need to redirect /// to the current page but the current page is actually a rewritten URL normally done with something like - /// Server.Transfer. + /// Server.Transfer. It is also handy if you want to persist the query strings. /// public class RedirectToUmbracoUrlResult : ActionResult { diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index 0d0e012f1a..64dcb2a04b 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -117,7 +117,7 @@ namespace Umbraco.Web.Mvc /// /// /// - private static PostedDataProxyInfo GetFormInfo(RequestContext requestContext) + internal static PostedDataProxyInfo GetFormInfo(RequestContext requestContext) { if (requestContext == null) throw new ArgumentNullException("requestContext"); @@ -201,7 +201,7 @@ namespace Umbraco.Web.Mvc /// /// /// - private IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo) + internal static IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo) { if (requestContext == null) throw new ArgumentNullException("requestContext"); if (postedInfo == null) throw new ArgumentNullException("postedInfo"); diff --git a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs index 7b94f9ad71..feb5b30ce2 100644 --- a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs @@ -34,6 +34,25 @@ namespace Umbraco.Web.Mvc requestContext.RouteData.DataTokens.Add("umbraco", renderModel); requestContext.RouteData.DataTokens.Add("umbraco-doc-request", umbracoContext.PublishedContentRequest); requestContext.RouteData.DataTokens.Add("umbraco-context", umbracoContext); + //this is used just for a flag that this is an umbraco custom route + requestContext.RouteData.DataTokens.Add("umbraco-custom-route", true); + + //Here we need to detect if a SurfaceController has posted + var formInfo = RenderRouteHandler.GetFormInfo(requestContext); + if (formInfo != null) + { + var def = new RouteDefinition + { + ActionName = requestContext.RouteData.GetRequiredString("action"), + ControllerName = requestContext.RouteData.GetRequiredString("controller"), + PublishedContentRequest = umbracoContext.PublishedContentRequest + }; + + //set the special data token to the current route definition + requestContext.RouteData.DataTokens["umbraco-route-def"] = def; + + return RenderRouteHandler.HandlePostedValues(requestContext, formInfo); + } return new MvcHandler(requestContext); } diff --git a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs new file mode 100644 index 0000000000..2bb2903aa0 --- /dev/null +++ b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; + +namespace Umbraco.Web.Routing +{ + /// + /// This url provider is used purely to deal with umbraco custom routes that utilize UmbracoVirtualNodeRouteHandler and will return + /// the URL returned from the current PublishedContentRequest.PublishedContent (virtual node) if the request is in fact a virtual route and + /// the id that is being requested matches the id of the current PublishedContentRequest.PublishedContent. + /// + internal class CustomRouteUrlProvider : IUrlProvider + { + /// + /// This will simply return the URL that is returned by the assigned IPublishedContent if this is a custom route + /// + /// + /// + /// + /// + /// + public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode) + { + if (umbracoContext == null) return null; + if (umbracoContext.PublishedContentRequest == null) return null; + if (umbracoContext.PublishedContentRequest.PublishedContent == null) return null; + if (umbracoContext.HttpContext == null) return null; + if (umbracoContext.HttpContext.Request == null) return null; + 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; + //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 + : null; + } + + /// + /// This always returns null because this url provider is used purely to deal with Umbraco custom routes with + /// UmbracoVirtualNodeRouteHandler, we really only care about the normal URL so that RedirectToCurrentUmbracoPage() works + /// with SurfaceControllers + /// + /// + /// + /// + /// + public IEnumerable GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current) + { + return null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index 5a9dd9123c..602a14dabb 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -133,7 +133,7 @@ namespace Umbraco.Web.Routing { if (mode == UrlProviderMode.Auto) { - if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) + if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) mode = UrlProviderMode.Relative; else mode = UrlProviderMode.Absolute; diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c5ae7c0c02..2b2ef055af 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -492,6 +492,7 @@ + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 88a44242dc..9853682b2d 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -352,8 +352,9 @@ namespace Umbraco.Web }); UrlProviderResolver.Current = new UrlProviderResolver( - //typeof(AliasUrlProvider), // not enabled by default - typeof(DefaultUrlProvider) + //typeof(AliasUrlProvider), // not enabled by default + typeof(DefaultUrlProvider), + typeof(CustomRouteUrlProvider) ); ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver(