Web.Routing - implement UrlProviderMode
This commit is contained in:
@@ -155,7 +155,7 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177));
|
||||
|
||||
SettingsForTests.UseDomainPrefixes = false;
|
||||
routingContext.UrlProvider.EnforceAbsoluteUrls = true;
|
||||
routingContext.UrlProvider.Mode = UrlProviderMode.Absolute;
|
||||
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177));
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace Umbraco.Tests.Routing
|
||||
SettingsForTests.UseDomainPrefixes = true;
|
||||
Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999));
|
||||
SettingsForTests.UseDomainPrefixes = false;
|
||||
routingContext.UrlProvider.EnforceAbsoluteUrls = true;
|
||||
routingContext.UrlProvider.Mode = UrlProviderMode.Absolute;
|
||||
Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.UrlProvider.GetUrl(100311));
|
||||
|
||||
SettingsForTests.UseDomainPrefixes = false;
|
||||
routingContext.UrlProvider.EnforceAbsoluteUrls = true;
|
||||
routingContext.UrlProvider.Mode = UrlProviderMode.Absolute;
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.UrlProvider.GetUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.UrlProvider.GetUrl(100311));
|
||||
}
|
||||
|
||||
@@ -11,14 +11,17 @@ namespace Umbraco.Web.Configuration
|
||||
internal class WebRouting : UmbracoConfigurationSection
|
||||
{
|
||||
private const string KeyTrySkipIisCustomErrors = "trySkipIisCustomErrors";
|
||||
private const string KeyUrlProviderMode = "urlProviderMode";
|
||||
|
||||
private bool? _trySkipIisCustomErrors;
|
||||
private Routing.UrlProviderMode? _urlProviderMode;
|
||||
|
||||
internal protected override void ResetSection()
|
||||
{
|
||||
base.ResetSection();
|
||||
|
||||
_trySkipIisCustomErrors = null;
|
||||
_urlProviderMode = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,5 +38,21 @@ namespace Umbraco.Web.Configuration
|
||||
}
|
||||
internal set { _trySkipIisCustomErrors = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the url provider mode.
|
||||
/// </summary>
|
||||
[ConfigurationProperty(KeyUrlProviderMode, DefaultValue = Routing.UrlProviderMode.AutoLegacy, IsRequired = false)]
|
||||
[TypeConverter(typeof(CaseInsensitiveEnumConfigConverter<Routing.UrlProviderMode>))]
|
||||
public Routing.UrlProviderMode UrlProviderMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _urlProviderMode ?? (IsPresent
|
||||
? (Routing.UrlProviderMode)this[KeyUrlProviderMode]
|
||||
: Routing.UrlProviderMode.Auto);
|
||||
}
|
||||
internal set { _urlProviderMode = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="contentCache">The content cache.</param>
|
||||
/// <param name="id">The published content id.</param>
|
||||
/// <param name="current">The current absolute url.</param>
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <param name="mode">The url mode.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on url indicated by <c>current</c> and settings, unless
|
||||
/// <c>absolute</c> is true, in which case the url is always absolute.</para>
|
||||
/// <para>If the provider is unable to provide a url, it should return <c>null</c>.</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, bool absolute)
|
||||
public string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, UrlProviderMode mode)
|
||||
{
|
||||
return null; // we have nothing to say
|
||||
}
|
||||
|
||||
@@ -23,14 +23,13 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="contentCache">The content cache.</param>
|
||||
/// <param name="id">The published content id.</param>
|
||||
/// <param name="current">The current absolute url.</param>
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <param name="mode">The url mode.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on url indicated by <c>current</c> and settings, unless
|
||||
/// <c>absolute</c> is true, in which case the url is always absolute.</para>
|
||||
/// <para>The url is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
|
||||
/// <para>If the provider is unable to provide a url, it should return <c>null</c>.</para>
|
||||
/// </remarks>
|
||||
public virtual string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, bool absolute)
|
||||
public virtual string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, UrlProviderMode mode)
|
||||
{
|
||||
DomainAndUri domainUri;
|
||||
string path;
|
||||
@@ -49,7 +48,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
// there was a route in the cache - extract domainUri and path
|
||||
// route is /<path> or <domainRootId>/<path>
|
||||
int pos = route.IndexOf('/');
|
||||
var pos = route.IndexOf('/');
|
||||
path = pos == 0 ? route : route.Substring(pos);
|
||||
domainUri = pos == 0 ? null : DomainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current);
|
||||
}
|
||||
@@ -97,7 +96,7 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
|
||||
// assemble the url from domainUri (maybe null) and path
|
||||
return AssembleUrl(domainUri, path, current, absolute).ToString();
|
||||
return AssembleUrl(domainUri, path, current, mode).ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -185,27 +184,65 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
#region Utilities
|
||||
|
||||
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, bool absolute)
|
||||
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode)
|
||||
{
|
||||
Uri uri;
|
||||
|
||||
if (domainUri == null)
|
||||
// ignore vdir at that point, UriFromUmbraco will do it
|
||||
|
||||
if (mode == UrlProviderMode.AutoLegacy)
|
||||
{
|
||||
// no domain was found : return an absolute or relative url
|
||||
// ignore vdir at that point
|
||||
if (!absolute || current == null)
|
||||
uri = new Uri(path, UriKind.Relative);
|
||||
else
|
||||
uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path);
|
||||
mode = Core.Configuration.UmbracoSettings.UseDomainPrefixes
|
||||
? UrlProviderMode.Absolute
|
||||
: UrlProviderMode.Auto;
|
||||
}
|
||||
else
|
||||
|
||||
if (mode == UrlProviderMode.AutoLegacy)
|
||||
{
|
||||
// a domain was found : return an absolute or relative url
|
||||
// ignore vdir at that point
|
||||
if (!absolute && current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority))
|
||||
uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); // relative
|
||||
else
|
||||
uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); // absolute
|
||||
mode = Core.Configuration.UmbracoSettings.UseDomainPrefixes
|
||||
? UrlProviderMode.Absolute
|
||||
: UrlProviderMode.Auto;
|
||||
}
|
||||
|
||||
if (domainUri == null) // no domain was found
|
||||
{
|
||||
if (current == null)
|
||||
mode = UrlProviderMode.Relative; // best we can do
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case UrlProviderMode.Absolute:
|
||||
uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path);
|
||||
break;
|
||||
case UrlProviderMode.Relative:
|
||||
case UrlProviderMode.Auto:
|
||||
uri = new Uri(path, UriKind.Relative);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("mode");
|
||||
}
|
||||
}
|
||||
else // a domain was found
|
||||
{
|
||||
if (mode == UrlProviderMode.Auto)
|
||||
{
|
||||
if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority))
|
||||
mode = UrlProviderMode.Relative;
|
||||
else
|
||||
mode = UrlProviderMode.Absolute;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case UrlProviderMode.Absolute:
|
||||
uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path));
|
||||
break;
|
||||
case UrlProviderMode.Relative:
|
||||
uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("mode");
|
||||
}
|
||||
}
|
||||
|
||||
// UriFromUmbraco will handle vdir
|
||||
|
||||
@@ -15,14 +15,13 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="contentCache">The content cache.</param>
|
||||
/// <param name="id">The published content id.</param>
|
||||
/// <param name="current">The current absolute url.</param>
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <param name="mode">The url mode.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on url indicated by <c>current</c> and settings, unless
|
||||
/// <c>absolute</c> is true, in which case the url is always absolute.</para>
|
||||
/// <para>The url is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
|
||||
/// <para>If the provider is unable to provide a url, it should return <c>null</c>.</para>
|
||||
/// </remarks>
|
||||
string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, bool absolute);
|
||||
string GetUrl(UmbracoContext umbracoContext, IPublishedContentStore contentCache, int id, Uri current, UrlProviderMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the other urls of a published content.
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing
|
||||
_umbracoContext = umbracoContext;
|
||||
_contentCache = contentCache;
|
||||
_urlProviders = urlProviders;
|
||||
EnforceAbsoluteUrls = false;
|
||||
Mode = UmbracoSettings.For<Configuration.WebRouting>().UrlProviderMode;
|
||||
}
|
||||
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
@@ -32,9 +32,9 @@ namespace Umbraco.Web.Routing
|
||||
private readonly IEnumerable<IUrlProvider> _urlProviders;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the provider should enforce absolute urls.
|
||||
/// Gets or sets the provider url mode.
|
||||
/// </summary>
|
||||
public bool EnforceAbsoluteUrls { get; set; }
|
||||
public UrlProviderMode Mode { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -46,13 +46,12 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="id">The published content identifier.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on the current url, settings, and options.</para>
|
||||
/// <para>The url is absolute or relative depending on <c>Mode</c> and on the current url.</para>
|
||||
/// <para>If the provider is unable to provide a url, it returns "#".</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(int id)
|
||||
{
|
||||
var absolute = UmbracoSettings.UseDomainPrefixes | EnforceAbsoluteUrls;
|
||||
return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, absolute);
|
||||
return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, Mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -62,14 +61,14 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on the current url and settings, unless <c>absolute</c> is true,
|
||||
/// in which case the url is always absolute.</para>
|
||||
/// <para>The url is absolute or relative depending on <c>Mode</c> and on <c>current</c>, unless
|
||||
/// <c>absolute</c> is true, in which case the url is always absolute.</para>
|
||||
/// <para>If the provider is unable to provide a url, it returns "#".</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(int id, bool absolute)
|
||||
{
|
||||
absolute = absolute | EnforceAbsoluteUrls;
|
||||
return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, absolute);
|
||||
var mode = absolute ? UrlProviderMode.Absolute : Mode;
|
||||
return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,14 +79,46 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on url indicated by <c>current</c> and settings, unless
|
||||
/// <para>The url is absolute or relative depending on <c>Mode</c> and on <c>current</c>, unless
|
||||
/// <c>absolute</c> is true, in which case the url is always absolute.</para>
|
||||
/// <para>If the provider is unable to provide a url, it returns "#".</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(int id, Uri current, bool absolute)
|
||||
{
|
||||
absolute = absolute | EnforceAbsoluteUrls;
|
||||
var url = _urlProviders.Select(provider => provider.GetUrl(_umbracoContext, _contentCache, id, current, absolute)).FirstOrDefault(u => u != null);
|
||||
var mode = absolute ? UrlProviderMode.Absolute : Mode;
|
||||
return GetUrl(id, current, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice url of a published content.
|
||||
/// </summary>
|
||||
/// <param name="id">The published content identifier.</param>
|
||||
/// <param name="mode">The url mode.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on <c>mode</c> and on the current url.</para>
|
||||
/// <para>If the provider is unable to provide a url, it returns "#".</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(int id, UrlProviderMode mode)
|
||||
{
|
||||
return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice url of a published content.
|
||||
/// </summary>
|
||||
/// <param name="id">The published content id.</param>
|
||||
/// <param name="current">The current absolute url.</param>
|
||||
/// <param name="mode">The url mode.</param>
|
||||
/// <returns>The url for the published content.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The url is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
|
||||
/// <para>If the provider is unable to provide a url, it returns "#".</para>
|
||||
/// </remarks>
|
||||
public string GetUrl(int id, Uri current, UrlProviderMode mode)
|
||||
{
|
||||
var url = _urlProviders.Select(provider => provider.GetUrl(_umbracoContext, _contentCache, id, current, mode))
|
||||
.FirstOrDefault(u => u != null);
|
||||
return url ?? "#"; // legacy wants this
|
||||
}
|
||||
|
||||
|
||||
36
src/Umbraco.Web/Routing/UrlProviderMode.cs
Normal file
36
src/Umbraco.Web/Routing/UrlProviderMode.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the type of urls that the url provider should produce.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The <c>AutoLegacy</c> option is equivalent to <c>Auto</c> but it also respects the legacy <c>useDomainPrefixes</c> setting.
|
||||
/// When that setting is true, then all urls are absolute. Otherwise, urls will be relative or absolute, depending on hostnames.</para>
|
||||
/// <para>The <c>Relative</c> option can lead to invalid results when combined with hostnames, but it is the only way to reproduce
|
||||
/// the true, pre-4.10, always-relative behavior of Umbraco.</para>
|
||||
/// <para>For the time being, the default option is <c>AutoLegacy</c> although in the future it will be <c>Auto</c>.</para>
|
||||
/// </remarks>
|
||||
internal enum UrlProviderMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should determine automatically whether to return relative or absolute urls,
|
||||
/// and also respect the legacy <c>useDomainPrefixes</c> setting.
|
||||
/// </summary>
|
||||
AutoLegacy,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should produce relative urls exclusively.
|
||||
/// </summary>
|
||||
Relative,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should produce absolute urls exclusively.
|
||||
/// </summary>
|
||||
Absolute,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the url provider should determine automatically whether to return relative or absolute urls.
|
||||
/// </summary>
|
||||
Auto
|
||||
}
|
||||
}
|
||||
@@ -325,6 +325,7 @@
|
||||
<Compile Include="Mvc\MemberAuthorizeAttribute.cs" />
|
||||
<Compile Include="Mvc\ControllerFactoryExtensions.cs" />
|
||||
<Compile Include="Mvc\SurfaceRouteHandler.cs" />
|
||||
<Compile Include="Routing\UrlProviderMode.cs" />
|
||||
<Compile Include="Search\ExamineIndexerModel.cs" />
|
||||
<Compile Include="Search\LuceneIndexerExtensions.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\AssignDomain2.aspx.cs">
|
||||
|
||||
Reference in New Issue
Block a user