diff --git a/src/Umbraco.Core/IO/IOHelperExtensions.cs b/src/Umbraco.Core/IO/IOHelperExtensions.cs
index 0e35f3b87b..6912974196 100644
--- a/src/Umbraco.Core/IO/IOHelperExtensions.cs
+++ b/src/Umbraco.Core/IO/IOHelperExtensions.cs
@@ -5,6 +5,19 @@ namespace Umbraco.Core.IO
{
public static class IOHelperExtensions
{
+ ///
+ /// Will resolve a virtual path URL to an absolute path, else if it is not a virtual path (i.e. starts with ~/) then
+ /// it will just return the path as-is (relative).
+ ///
+ ///
+ ///
+ ///
+ public static string ResolveRelativeOrVirtualUrl(this IIOHelper ioHelper, string path)
+ {
+ if (string.IsNullOrWhiteSpace(path)) return path;
+ return path.StartsWith("~/") ? ioHelper.ResolveUrl(path) : path;
+ }
+
///
/// Tries to create a directory.
///
diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs
index fcd36d8a7e..298047754c 100644
--- a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs
+++ b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs
@@ -141,7 +141,7 @@ namespace Umbraco.Core.Manifest
Alias = _definition.Alias,
Name = _definition.Name,
Icon = _definition.Icon,
- View = _ioHelper.ResolveUrl(_definition.View),
+ View = _ioHelper.ResolveRelativeOrVirtualUrl(_definition.View),
Weight = _definition.Weight
};
}
diff --git a/src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs b/src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs
index 7b0e85d8dc..9a6b37a9bb 100644
--- a/src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs
+++ b/src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs
@@ -140,7 +140,7 @@ namespace Umbraco.Core.Manifest
private string RewriteVirtualUrl(JValue view)
{
- return _ioHelper.ResolveUrl(view.Value as string);
+ return _ioHelper.ResolveRelativeOrVirtualUrl(view.Value as string);
}
private void PrepareForParameterEditor(JObject jobject, DataEditor target)
diff --git a/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs b/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs
index a2bfd340e5..c6ffb9b6ef 100644
--- a/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs
+++ b/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs
@@ -195,21 +195,21 @@ namespace Umbraco.Core.Manifest
// scripts and stylesheets are raw string, must process here
for (var i = 0; i < manifest.Scripts.Length; i++)
- manifest.Scripts[i] = _ioHelper.ResolveUrl(manifest.Scripts[i]);
+ manifest.Scripts[i] = _ioHelper.ResolveRelativeOrVirtualUrl(manifest.Scripts[i]);
for (var i = 0; i < manifest.Stylesheets.Length; i++)
- manifest.Stylesheets[i] = _ioHelper.ResolveUrl(manifest.Stylesheets[i]);
+ manifest.Stylesheets[i] = _ioHelper.ResolveRelativeOrVirtualUrl(manifest.Stylesheets[i]);
foreach (var contentApp in manifest.ContentApps)
{
- contentApp.View = _ioHelper.ResolveUrl(contentApp.View);
+ contentApp.View = _ioHelper.ResolveRelativeOrVirtualUrl(contentApp.View);
}
foreach (var dashboard in manifest.Dashboards)
{
- dashboard.View = _ioHelper.ResolveUrl(dashboard.View);
+ dashboard.View = _ioHelper.ResolveRelativeOrVirtualUrl(dashboard.View);
}
foreach (var gridEditor in manifest.GridEditors)
{
- gridEditor.View = _ioHelper.ResolveUrl(gridEditor.View);
- gridEditor.Render = _ioHelper.ResolveUrl(gridEditor.Render);
+ gridEditor.View = _ioHelper.ResolveRelativeOrVirtualUrl(gridEditor.View);
+ gridEditor.Render = _ioHelper.ResolveRelativeOrVirtualUrl(gridEditor.Render);
}
// add property editors that are also parameter editors, to the parameter editors list
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ConfigurationEditorOfTConfiguration.cs b/src/Umbraco.Infrastructure/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
index 39cd91599b..0efa42929a 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
@@ -36,7 +36,7 @@ namespace Umbraco.Core.PropertyEditors
ConfigurationField field;
- var attributeView = ioHelper.ResolveUrl(attribute.View);
+ var attributeView = ioHelper.ResolveRelativeOrVirtualUrl(attribute.View);
// if the field does not have its own type, use the base type
if (attribute.Type == null)
{
diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml
index a150e0c7e3..0216c7846a 100644
--- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml
@@ -25,7 +25,7 @@
-
+
diff --git a/src/Umbraco.Web/Security/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
index c2f7c00b35..97cc96d81b 100644
--- a/src/Umbraco.Web/Security/AppBuilderExtensions.cs
+++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
@@ -252,7 +252,7 @@ namespace Umbraco.Web.Security
Current.Configs.Global(),
Current.Configs.Security(),
app.CreateLogger(),
- Current.IOHelper);
+ Current.HostingEnvironment);
//This is required so that we can read the auth ticket format outside of this pipeline
app.CreatePerOwinContext(
diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs
index 30d3fe5041..cd72b2faf9 100644
--- a/src/Umbraco.Web/UmbracoApplication.cs
+++ b/src/Umbraco.Web/UmbracoApplication.cs
@@ -36,7 +36,8 @@ namespace Umbraco.Web
var requestCache = new HttpRequestAppCache(() => HttpContext.Current?.Items);
var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker();
- return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, GetTypeFinder(), requestCache, umbracoBootPermissionChecker);
+ return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom,
+ GetTypeFinder(hostingEnvironment, logger, profiler), requestCache, umbracoBootPermissionChecker);
}
}
}
diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs
index 5e1c3cd954..d884366bf1 100644
--- a/src/Umbraco.Web/UmbracoApplicationBase.cs
+++ b/src/Umbraco.Web/UmbracoApplicationBase.cs
@@ -79,19 +79,22 @@ namespace Umbraco.Web
///
/// Gets a
///
+ ///
+ ///
+ ///
///
- protected virtual ITypeFinder GetTypeFinder()
+ protected virtual ITypeFinder GetTypeFinder(IHostingEnvironment hostingEnvironment, ILogger logger, IProfiler profiler)
{
// TODO: Currently we are not passing in any TypeFinderConfig (with ITypeFinderSettings) which we should do, however
// this is not critical right now and would require loading in some config before boot time so just leaving this as-is for now.
var runtimeHashPaths = new RuntimeHashPaths();
// the bin folder and everything in it
- runtimeHashPaths.AddFolder(new DirectoryInfo(Current.IOHelper.MapPath("~/bin")));
+ runtimeHashPaths.AddFolder(new DirectoryInfo(hostingEnvironment.MapPath("~/bin")));
// the app code folder and everything in it
- runtimeHashPaths.AddFile(new FileInfo(Current.IOHelper.MapPath("~/App_Code")));
+ runtimeHashPaths.AddFile(new FileInfo(hostingEnvironment.MapPath("~/App_Code")));
// global.asax (the app domain also monitors this, if it changes will do a full restart)
- runtimeHashPaths.AddFile(new FileInfo(Current.IOHelper.MapPath("~/global.asax")));
- var runtimeHash = new RuntimeHash(new ProfilingLogger(Current.Logger, Current.Profiler), runtimeHashPaths);
+ runtimeHashPaths.AddFile(new FileInfo(hostingEnvironment.MapPath("~/global.asax")));
+ var runtimeHash = new RuntimeHash(new ProfilingLogger(logger, profiler), runtimeHashPaths);
return new TypeFinder(Logger, new DefaultUmbracoAssemblyProvider(
// GetEntryAssembly was actually an exposed API by request of the aspnetcore team which works in aspnet core because a website
// in that case is essentially an exe. However in netframework there is no entry assembly, things don't really work that way since