diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs index ba9fd99f0f..25e87f23d8 100644 --- a/src/Umbraco.Core/UriExtensions.cs +++ b/src/Umbraco.Core/UriExtensions.cs @@ -59,6 +59,16 @@ namespace Umbraco.Core } } + public static string GetAbsolutePathDecoded(this Uri uri) + { + return System.Web.HttpUtility.UrlDecode(uri.AbsolutePath); + } + + public static string GetSafeAbsolutePathDecoded(this Uri uri) + { + return System.Web.HttpUtility.UrlDecode(uri.GetSafeAbsolutePath()); + } + // Creates a new Uri with path ending with a slash // Everything else is unchanged but for the fragment which is lost public static Uri EndPathWithSlash(this Uri uri) diff --git a/src/Umbraco.Web/Routing/LookupByAlias.cs b/src/Umbraco.Web/Routing/LookupByAlias.cs index e98aff6ca7..0c0c023d23 100644 --- a/src/Umbraco.Web/Routing/LookupByAlias.cs +++ b/src/Umbraco.Web/Routing/LookupByAlias.cs @@ -3,6 +3,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco.interfaces; +using Umbraco.Core; namespace Umbraco.Web.Routing { @@ -31,7 +32,7 @@ namespace Umbraco.Web.Routing node = docRequest.RoutingContext.PublishedContentStore.GetDocumentByUrlAlias( docRequest.RoutingContext.UmbracoContext, docRequest.HasDomain ? docRequest.Domain.RootNodeId : 0, - docRequest.Uri.AbsolutePath); + docRequest.Uri.GetAbsolutePathDecoded()); if (node != null) { diff --git a/src/Umbraco.Web/Routing/LookupByIdPath.cs b/src/Umbraco.Web/Routing/LookupByIdPath.cs index 26b2537126..6192bfb0c3 100644 --- a/src/Umbraco.Web/Routing/LookupByIdPath.cs +++ b/src/Umbraco.Web/Routing/LookupByIdPath.cs @@ -4,6 +4,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco.interfaces; +using Umbraco.Core; namespace Umbraco.Web.Routing { @@ -24,11 +25,12 @@ namespace Umbraco.Web.Routing public bool TrySetDocument(PublishedContentRequest docRequest) { IPublishedContent node = null; + var path = docRequest.Uri.GetAbsolutePathDecoded(); int nodeId = -1; - if (docRequest.Uri.AbsolutePath != "/") // no id if "/" + if (path != "/") // no id if "/" { - string noSlashPath = docRequest.Uri.AbsolutePath.Substring(1); + string noSlashPath = path.Substring(1); if (!Int32.TryParse(noSlashPath, out nodeId)) nodeId = -1; diff --git a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs index 21887ed7f6..68201051bb 100644 --- a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs +++ b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs @@ -3,6 +3,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco.interfaces; +using Umbraco.Core; namespace Umbraco.Web.Routing { @@ -24,10 +25,10 @@ namespace Umbraco.Web.Routing { string route; if (docRequest.HasDomain) - route = docRequest.Domain.RootNodeId.ToString() + DomainHelper.PathRelativeToDomain(docRequest.DomainUri, docRequest.Uri.AbsolutePath); + route = docRequest.Domain.RootNodeId.ToString() + DomainHelper.PathRelativeToDomain(docRequest.DomainUri, docRequest.Uri.GetAbsolutePathDecoded()); else - route = docRequest.Uri.AbsolutePath; - + route = docRequest.Uri.GetAbsolutePathDecoded(); + var node = LookupDocumentNode(docRequest, route); return node != null; } diff --git a/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs index 57e28cbf4e..f6b29631d4 100644 --- a/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs @@ -3,6 +3,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco.cms.businesslogic.template; +using Umbraco.Core; namespace Umbraco.Web.Routing { @@ -25,14 +26,15 @@ namespace Umbraco.Web.Routing public override bool TrySetDocument(PublishedContentRequest docRequest) { IPublishedContent node = null; - string path = docRequest.Uri.AbsolutePath; + string path = docRequest.Uri.GetAbsolutePathDecoded(); if (docRequest.HasDomain) path = DomainHelper.PathRelativeToDomain(docRequest.DomainUri, path); + if (path != "/") // no template if "/" { - var pos = docRequest.Uri.AbsolutePath.LastIndexOf('/'); - var templateAlias = docRequest.Uri.AbsolutePath.Substring(pos + 1); + var pos = path.LastIndexOf('/'); + var templateAlias = path.Substring(pos + 1); path = pos == 0 ? "/" : path.Substring(0, pos); //TODO: We need to check if the altTemplate is for MVC or not, though I'm not exactly sure how the best diff --git a/src/Umbraco.Web/Routing/LookupByProfile.cs b/src/Umbraco.Web/Routing/LookupByProfile.cs index dbaa40ecae..ea99ea24c5 100644 --- a/src/Umbraco.Web/Routing/LookupByProfile.cs +++ b/src/Umbraco.Web/Routing/LookupByProfile.cs @@ -3,6 +3,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco; +using Umbraco.Core; namespace Umbraco.Web.Routing { @@ -25,13 +26,14 @@ namespace Umbraco.Web.Routing public override bool TrySetDocument(PublishedContentRequest docRequest) { IPublishedContent node = null; + var path = docRequest.Uri.GetAbsolutePathDecoded(); bool isProfile = false; - var pos = docRequest.Uri.AbsolutePath.LastIndexOf('/'); + var pos = path.LastIndexOf('/'); if (pos > 0) { - var memberLogin = docRequest.Uri.AbsolutePath.Substring(pos + 1); - var path = docRequest.Uri.AbsolutePath.Substring(0, pos); + var memberLogin = path.Substring(pos + 1); + path = path.Substring(0, pos); if (path == GlobalSettings.ProfileUrl) { diff --git a/src/Umbraco.Web/UriUtility.cs b/src/Umbraco.Web/UriUtility.cs index 076305e79a..7b5833f606 100644 --- a/src/Umbraco.Web/UriUtility.cs +++ b/src/Umbraco.Web/UriUtility.cs @@ -82,6 +82,8 @@ namespace Umbraco.Web // ie no virtual directory, no .aspx, lowercase... public static Uri UriToUmbraco(Uri uri) { + // note: no need to decode uri here because we're returning a uri + // so it will be re-encoded anyway var path = uri.GetSafeAbsolutePath(); path = path.ToLower();