From 55d9af2b68d6c1b4588c2b7f600c3c5715309d83 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 27 Apr 2020 10:09:10 +0200 Subject: [PATCH] #6233- Install steps + MacroRenderer --- .../DefaultUmbracoAssemblyProvider.cs | 2 + .../Composing/ReferenceResolver.cs | 42 ++++-- src/Umbraco.Core/Composing/TypeFinder.cs | 11 +- .../Composing/TypeFinderConfig.cs | 2 +- .../Configuration/ConfigsExtensions.cs | 3 + .../Persistence/DbProviderFactoryCreator.cs | 65 +++++++++ .../AspNetCore/AspNetCoreRequestAccessor.cs | 3 +- .../AspNetCore/UmbracoViewPage.cs | 94 +++++++++++++ .../UmbracoCoreServiceCollectionExtensions.cs | 21 ++- .../Install/InstallController.cs | 3 +- .../Macros/MacroRenderer.cs | 6 +- .../Macros/PartialViewMacroEngine.cs | 124 ++++++++++++++++++ .../Macros/PartialViewMacroPage.cs | 11 ++ .../src/installer/steps/user.html | 4 +- src/Umbraco.Web.UI.NetCore/Startup.cs | 4 +- .../Umbraco.Web.UI.NetCore.csproj | 1 + 16 files changed, 362 insertions(+), 34 deletions(-) create mode 100644 src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs create mode 100644 src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs create mode 100644 src/Umbraco.Web.Common/Macros/PartialViewMacroEngine.cs create mode 100644 src/Umbraco.Web.Common/Macros/PartialViewMacroPage.cs diff --git a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs index 4d153d8922..54db9d8a99 100644 --- a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs +++ b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs @@ -25,6 +25,8 @@ namespace Umbraco.Core.Composing "Umbraco.Web.Common", "Umbraco.Web.BackOffice", "Umbraco.Web.Website", + "Umbraco.Web.NetCore", + "System.Data.SqlServerCe" }; public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly) diff --git a/src/Umbraco.Core/Composing/ReferenceResolver.cs b/src/Umbraco.Core/Composing/ReferenceResolver.cs index 65dba8bf23..61444c55ce 100644 --- a/src/Umbraco.Core/Composing/ReferenceResolver.cs +++ b/src/Umbraco.Core/Composing/ReferenceResolver.cs @@ -51,7 +51,7 @@ namespace Umbraco.Core.Composing // Load in each assembly in the directory of the entry assembly to be included in the search // for Umbraco dependencies/transitive dependencies foreach(var dir in assemblyLocations) - { + { foreach(var dll in Directory.EnumerateFiles(dir, "*.dll")) { var assemblyName = AssemblyName.GetAssemblyName(dll); @@ -65,14 +65,15 @@ namespace Umbraco.Core.Composing if (assemblyName.FullName.StartsWith("Umbraco.")) continue; - var assembly = Assembly.Load(assemblyName); + var assembly = Assembly.LoadFrom(dll); assemblies.Add(assembly); } } + var assemblyNameToAssembly = assemblies.ToDictionary(x => x.GetName()); foreach (var item in assemblies) { - var classification = Resolve(item); + var classification = Resolve(item, assemblyNameToAssembly); if (classification == Classification.ReferencesUmbraco || classification == Classification.IsUmbraco) { applicationParts.Add(item); @@ -100,7 +101,7 @@ namespace Umbraco.Core.Composing return assembly.Location; } - private Classification Resolve(Assembly assembly) + private Classification Resolve(Assembly assembly, IDictionary assemblyNameToAssembly) { if (_classifications.TryGetValue(assembly, out var classification)) { @@ -110,12 +111,12 @@ namespace Umbraco.Core.Composing // Initialize the dictionary with a value to short-circuit recursive references. classification = Classification.Unknown; _classifications[assembly] = classification; - + if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => assembly.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase))) { // if its part of the filter it doesn't reference umbraco classification = Classification.DoesNotReferenceUmbraco; - } + } else if (_umbracoAssemblies.Contains(assembly.GetName().Name)) { classification = Classification.IsUmbraco; @@ -123,10 +124,10 @@ namespace Umbraco.Core.Composing else { classification = Classification.DoesNotReferenceUmbraco; - foreach (var reference in GetReferences(assembly)) + foreach (var reference in GetReferences(assembly, assemblyNameToAssembly)) { // recurse - var referenceClassification = Resolve(reference); + var referenceClassification = Resolve(reference, assemblyNameToAssembly); if (referenceClassification == Classification.IsUmbraco || referenceClassification == Classification.ReferencesUmbraco) { @@ -141,22 +142,37 @@ namespace Umbraco.Core.Composing return classification; } - protected virtual IEnumerable GetReferences(Assembly assembly) - { - foreach (var referenceName in assembly.GetReferencedAssemblies()) + protected virtual IEnumerable GetReferences(Assembly assembly, IDictionary assemblyNameToAssembly) + { + var referencedAssemblies = assembly.GetReferencedAssemblies(); + + foreach (var referenceName in referencedAssemblies) { // don't include if this is excluded if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => referenceName.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase))) continue; - var reference = Assembly.Load(referenceName); + Assembly reference ; + try + { + reference = Assembly.Load(referenceName); + } + catch (Exception) + { + if (!assemblyNameToAssembly.TryGetValue(referenceName, out var item)) + { + continue; + } + + reference = Assembly.LoadFrom(item.Location); + } if (!_lookup.Contains(reference)) { // A dependency references an item that isn't referenced by this project. // We'll add this reference so that we can calculate the classification. - _lookup.Add(reference); + _lookup.Add(reference); } yield return reference; } diff --git a/src/Umbraco.Core/Composing/TypeFinder.cs b/src/Umbraco.Core/Composing/TypeFinder.cs index 645182d66b..e1b355629e 100644 --- a/src/Umbraco.Core/Composing/TypeFinder.cs +++ b/src/Umbraco.Core/Composing/TypeFinder.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Composing _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _assemblyProvider = assemblyProvider; _runtimeHash = runtimeHash; - _assembliesAcceptingLoadExceptions = typeFinderConfig?.AssembliesAcceptingLoadExceptions.Where(x => !x.IsNullOrWhiteSpace()).ToArray() ?? Array.Empty(); + _assembliesAcceptingLoadExceptions = typeFinderConfig?.AssembliesAcceptingLoadExceptions.Where(x => !x.IsNullOrWhiteSpace()).ToArray() ?? Array.Empty(); } private bool AcceptsLoadExceptions(Assembly a) @@ -142,7 +142,10 @@ namespace Umbraco.Core.Composing "ServiceStack.", "SqlCE4Umbraco,", "Superpower,", // used by Serilog - "System.", + // "System.", + "System.Data.SqlClient,", + "System.Runtime,", + "System.Runtime.", "TidyNet,", "TidyNet.", "WebDriver,", @@ -192,7 +195,7 @@ namespace Umbraco.Core.Composing return GetClassesWithBaseType(assignTypeFrom, assemblyList, onlyConcreteClasses); } - + /// /// Finds any classes with the attribute. /// @@ -234,7 +237,7 @@ namespace Umbraco.Core.Composing // It didn't parse, so try loading from each already loaded assembly and cache it return TypeNamesCache.GetOrAdd(name, s => - AppDomain.CurrentDomain.GetAssemblies() + GetAllAssemblies() .Select(x => x.GetType(s)) .FirstOrDefault(x => x != null)); } diff --git a/src/Umbraco.Core/Composing/TypeFinderConfig.cs b/src/Umbraco.Core/Composing/TypeFinderConfig.cs index 3dc672b27c..9a3cd7072c 100644 --- a/src/Umbraco.Core/Composing/TypeFinderConfig.cs +++ b/src/Umbraco.Core/Composing/TypeFinderConfig.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Composing /// /// TypeFinder config via appSettings /// - internal class TypeFinderConfig : ITypeFinderConfig + public class TypeFinderConfig : ITypeFinderConfig { private readonly ITypeFinderSettings _settings; private IEnumerable _assembliesAcceptingLoadExceptions; diff --git a/src/Umbraco.Core/Configuration/ConfigsExtensions.cs b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs index f9ea352399..a4bdb5c55f 100644 --- a/src/Umbraco.Core/Configuration/ConfigsExtensions.cs +++ b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs @@ -28,6 +28,9 @@ namespace Umbraco.Core public static ISecuritySettings Security(this Configs configs) => configs.GetConfig(); + public static ITypeFinderSettings TypeFinder(this Configs configs) + => configs.GetConfig(); + public static IUserPasswordConfiguration UserPasswordConfiguration(this Configs configs) => configs.GetConfig(); diff --git a/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs b/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs new file mode 100644 index 0000000000..9d988e7dfe --- /dev/null +++ b/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence +{ + public class DbProviderFactoryCreator : IDbProviderFactoryCreator + { + private readonly string _defaultProviderName; + private readonly Func _getFactory; + private readonly IDictionary _syntaxProviders; + private readonly IDictionary _bulkSqlInsertProviders; + private readonly Action _createDatabaseAction; + + public DbProviderFactoryCreator(string defaultProviderName, + Func getFactory, + IDictionary syntaxProviders, + IDictionary bulkSqlInsertProviders, + Action createDatabaseAction) + { + _defaultProviderName = defaultProviderName; + _getFactory = getFactory; + _syntaxProviders = syntaxProviders; + _bulkSqlInsertProviders = bulkSqlInsertProviders; + _createDatabaseAction = createDatabaseAction; + } + + public DbProviderFactory CreateFactory() => CreateFactory(_defaultProviderName); + + public DbProviderFactory CreateFactory(string providerName) + { + if (string.IsNullOrEmpty(providerName)) return null; + return _getFactory(providerName); + } + + // gets the sql syntax provider that corresponds, from attribute + public ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName) + { + + if(!_syntaxProviders.TryGetValue(providerName, out var result)) + { + throw new InvalidOperationException($"Unknown provider name \"{providerName}\""); + } + + return result; + } + + public IBulkSqlInsertProvider CreateBulkSqlInsertProvider(string providerName) + { + + if(!_bulkSqlInsertProviders.TryGetValue(providerName, out var result)) + { + return new BasicBulkSqlInsertProvider(); + } + + return result; + } + + public void CreateDatabase() + { + _createDatabaseAction(); + } + } +} diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs index f2a15e1fc7..e323278809 100644 --- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs @@ -28,7 +28,7 @@ namespace Umbraco.Web.Common.AspNetCore private void RequestStart(object sender, HttpContext e) { - var reason = EnsureRoutableOutcome.IsRoutable; + var reason = EnsureRoutableOutcome.IsRoutable; //TODO get the correct value here like in UmbracoInjectedModule RouteAttempt?.Invoke(sender, new RoutableAttemptEventArgs(reason, _umbracoContextAccessor.UmbracoContext)); } @@ -41,7 +41,6 @@ namespace Umbraco.Web.Common.AspNetCore public event EventHandler EndRequest; - //TODO implement public event EventHandler RouteAttempt; public Uri GetRequestUrl() => _httpContextAccessor.HttpContext != null ? new Uri(_httpContextAccessor.HttpContext.Request.GetEncodedUrl()) : null; } diff --git a/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs b/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs new file mode 100644 index 0000000000..720024ead1 --- /dev/null +++ b/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs @@ -0,0 +1,94 @@ +using System; +using System.Text; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.AspNetCore.Mvc.Razor; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Composing; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Logging; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Strings; + +namespace Umbraco.Web.Common.AspNetCore +{ + + public abstract class UmbracoViewPage : UmbracoViewPage + { + + } + + public abstract class UmbracoViewPage : RazorPage + { + private IUmbracoContext _umbracoContext; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IGlobalSettings _globalSettings; + private readonly IContentSettings _contentSettings; + private readonly IProfilerHtml _profilerHtml; + + protected IUmbracoContext UmbracoContext => _umbracoContext ??= _umbracoContextAccessor.UmbracoContext; + + protected UmbracoViewPage() + { + _umbracoContextAccessor = Context.RequestServices.GetRequiredService(); + _globalSettings = Context.RequestServices.GetRequiredService(); + _contentSettings = Context.RequestServices.GetRequiredService(); + _profilerHtml = Context.RequestServices.GetRequiredService(); + } + + + public override void Write(object value) + { + if (value is IHtmlEncodedString htmlEncodedString) + { + base.WriteLiteral(htmlEncodedString.ToHtmlString()); + } + else + { + base.Write(value); + } + } + + public override void WriteLiteral(object value) + { + // filter / add preview banner + if (Context.Response.ContentType.InvariantEquals("text/html")) // ASP.NET default value + { + if (UmbracoContext.IsDebug || UmbracoContext.InPreviewMode) + { + var text = value.ToString(); + var pos = text.IndexOf("", StringComparison.InvariantCultureIgnoreCase); + + if (pos > -1) + { + string markupToInject; + + if (UmbracoContext.InPreviewMode) + { + // creating previewBadge markup + markupToInject = + string.Format(_contentSettings.PreviewBadge, + Current.IOHelper.ResolveUrl(_globalSettings.UmbracoPath), + Context.Request.GetEncodedUrl(), + UmbracoContext.PublishedRequest.PublishedContent.Id); + } + else + { + // creating mini-profiler markup + markupToInject = _profilerHtml.Render(); + } + + var sb = new StringBuilder(text); + sb.Insert(pos, markupToInject); + + base.WriteLiteral(sb.ToString()); + return; + } + } + } + + base.WriteLiteral(value); + } + } +} diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index 0fe784f421..bf6f537449 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Data.Common; +using System.Data.SqlClient; using System.IO; using System.Reflection; using Microsoft.AspNetCore.Hosting; @@ -134,7 +135,9 @@ namespace Umbraco.Web.Common.Extensions var globalSettings = configs.Global(); var umbracoVersion = new UmbracoVersion(globalSettings); + var typeFinder = CreateTypeFinder(logger, profiler, webHostEnvironment, entryAssembly, configs.TypeFinder()); + RegisterDatabaseTypes(typeFinder); var coreRuntime = GetCoreRuntime( configs, umbracoVersion, @@ -143,7 +146,7 @@ namespace Umbraco.Web.Common.Extensions profiler, hostingEnvironment, backOfficeInfo, - CreateTypeFinder(logger, profiler, webHostEnvironment, entryAssembly), + typeFinder, requestCache); factory = coreRuntime.Configure(container); @@ -151,14 +154,22 @@ namespace Umbraco.Web.Common.Extensions return services; } - private static ITypeFinder CreateTypeFinder(Core.Logging.ILogger logger, IProfiler profiler, IWebHostEnvironment webHostEnvironment, Assembly entryAssembly) + private static void RegisterDatabaseTypes(ITypeFinder typeFinder) + { + // need to manually register this factory + DbProviderFactories.RegisterFactory(Core.Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance); + var sqlCe = typeFinder.GetTypeByName("System.Data.SqlServerCe.SqlCeProviderFactory"); + if (!(sqlCe is null)) + { + DbProviderFactories.RegisterFactory(Core.Constants.DbProviderNames.SqlCe, sqlCe ); + } + } + private static ITypeFinder CreateTypeFinder(Core.Logging.ILogger logger, IProfiler profiler, IWebHostEnvironment webHostEnvironment, Assembly entryAssembly, ITypeFinderSettings typeFinderSettings) { - // 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(); runtimeHashPaths.AddFolder(new DirectoryInfo(Path.Combine(webHostEnvironment.ContentRootPath, "bin"))); var runtimeHash = new RuntimeHash(new ProfilingLogger(logger, profiler), runtimeHashPaths); - return new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(entryAssembly), runtimeHash); + return new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(entryAssembly), runtimeHash, new TypeFinderConfig(typeFinderSettings)); } private static IRuntime GetCoreRuntime( diff --git a/src/Umbraco.Web.Common/Install/InstallController.cs b/src/Umbraco.Web.Common/Install/InstallController.cs index e40f4bcfa7..9762a6505e 100644 --- a/src/Umbraco.Web.Common/Install/InstallController.cs +++ b/src/Umbraco.Web.Common/Install/InstallController.cs @@ -4,6 +4,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Hosting; using Umbraco.Core.WebAssets; +using Umbraco.Web.Common.Filters; using Umbraco.Web.Install; using Umbraco.Web.Security; @@ -42,7 +43,7 @@ namespace Umbraco.Web.Common.Install } [HttpGet] - // [StatusCodeResult(System.Net.HttpStatusCode.ServiceUnavailable)] //TODO reintroduce + [StatusCodeResult(System.Net.HttpStatusCode.ServiceUnavailable)] public ActionResult Index() { if (_runtime.Level == RuntimeLevel.Run) diff --git a/src/Umbraco.Web.Common/Macros/MacroRenderer.cs b/src/Umbraco.Web.Common/Macros/MacroRenderer.cs index 36f0224141..ee420c1d12 100644 --- a/src/Umbraco.Web.Common/Macros/MacroRenderer.cs +++ b/src/Umbraco.Web.Common/Macros/MacroRenderer.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Macros; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Web.Common.Macros; namespace Umbraco.Web.Macros { @@ -348,9 +349,8 @@ namespace Umbraco.Web.Macros /// The text output of the macro execution. private MacroContent ExecutePartialView(MacroModel macro, IPublishedContent content) { - throw new NotImplementedException(); - // var engine = new PartialViewMacroEngine(_umbracoContextAccessor, _httpContextAccessor, _ioHelper); - // return engine.Execute(macro, content); + var engine = new PartialViewMacroEngine(_umbracoContextAccessor, _httpContextAccessor, _ioHelper); + return engine.Execute(macro, content); } #endregion diff --git a/src/Umbraco.Web.Common/Macros/PartialViewMacroEngine.cs b/src/Umbraco.Web.Common/Macros/PartialViewMacroEngine.cs new file mode 100644 index 0000000000..16ba6f985f --- /dev/null +++ b/src/Umbraco.Web.Common/Macros/PartialViewMacroEngine.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewComponents; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Routing; +using Umbraco.Core.IO; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Web.Common.Extensions; +using Umbraco.Web.Macros; + +namespace Umbraco.Web.Common.Macros +{ + /// + /// A macro engine using MVC Partial Views to execute. + /// + public class PartialViewMacroEngine + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IIOHelper _ioHelper; + private readonly Func _getUmbracoContext; + + public PartialViewMacroEngine(IUmbracoContextAccessor umbracoContextAccessor, + IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper) + { + _httpContextAccessor = httpContextAccessor; + _ioHelper = ioHelper; + + _getUmbracoContext = () => + { + var context = umbracoContextAccessor.UmbracoContext; + if (context == null) + throw new InvalidOperationException( + $"The {GetType()} cannot execute with a null UmbracoContext.Current reference."); + return context; + }; + } + + public bool Validate(string code, string tempFileName, IPublishedContent currentPage, out string errorMessage) + { + var temp = GetVirtualPathFromPhysicalPath(tempFileName); + try + { + CompileAndInstantiate(temp); + } + catch (Exception exception) + { + errorMessage = exception.Message; + return false; + } + + errorMessage = string.Empty; + return true; + } + + public MacroContent Execute(MacroModel macro, IPublishedContent content) + { + if (macro == null) throw new ArgumentNullException(nameof(macro)); + if (content == null) throw new ArgumentNullException(nameof(content)); + if (string.IsNullOrWhiteSpace(macro.MacroSource)) + throw new ArgumentException("The MacroSource property of the macro object cannot be null or empty"); + + var httpContext = _httpContextAccessor.GetRequiredHttpContext(); + var umbCtx = _getUmbracoContext(); + var routeVals = new RouteData(); + routeVals.Values.Add("controller", "PartialViewMacro"); + routeVals.Values.Add("action", "Index"); + routeVals.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); //required for UmbracoViewPage + + //lets render this controller as a child action + var viewContext = new ViewContext(); + //try and extract the current view context from the route values, this would be set in the UmbracoViewPage or in + // the UmbracoPageResult if POSTing to an MVC controller but rendering in Webforms + + routeVals.DataTokens.Add("ParentActionViewContext", viewContext); + + var viewComponent = new PartialViewMacroViewComponent(macro, content); + + var writer = new StringWriter(); + var viewComponentContext = new ViewComponentContext( + new ViewComponentDescriptor(), + new Dictionary(), + HtmlEncoder.Default, + viewContext, + writer); + + viewComponent.InvokeAsync().GetAwaiter().GetResult().Execute(viewComponentContext); + + var output = writer.GetStringBuilder().ToString(); + + return new MacroContent { Text = output }; + } + + private string GetVirtualPathFromPhysicalPath(string physicalPath) + { + var rootpath = _ioHelper.MapPath("~/"); + physicalPath = physicalPath.Replace(rootpath, ""); + physicalPath = physicalPath.Replace("\\", "/"); + return "~/" + physicalPath; + } + + private static PartialViewMacroPage CompileAndInstantiate(string virtualPath) + { + // //Compile Razor - We Will Leave This To ASP.NET Compilation Engine & ASP.NET WebPages + // //Security in medium trust is strict around here, so we can only pass a virtual file path + // //ASP.NET Compilation Engine caches returned types + // //Changed From BuildManager As Other Properties Are Attached Like Context Path/ + // var webPageBase = WebPageBase.CreateInstanceFromVirtualPath(virtualPath); + // var webPage = webPageBase as PartialViewMacroPage; + // if (webPage == null) + // throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName); + // return webPage; + + //TODO? How to check this + return null; + } + } + +} diff --git a/src/Umbraco.Web.Common/Macros/PartialViewMacroPage.cs b/src/Umbraco.Web.Common/Macros/PartialViewMacroPage.cs new file mode 100644 index 0000000000..ee80c40a53 --- /dev/null +++ b/src/Umbraco.Web.Common/Macros/PartialViewMacroPage.cs @@ -0,0 +1,11 @@ +using Umbraco.Web.Common.AspNetCore; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Common.Macros +{ + /// + /// The base view class that PartialViewMacro views need to inherit from + /// + public abstract class PartialViewMacroPage : UmbracoViewPage + { } +} diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/user.html b/src/Umbraco.Web.UI.Client/src/installer/steps/user.html index a7ebc33f39..d2aeb6cdc4 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/user.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/user.html @@ -1,7 +1,7 @@ 
-

Install Umbraco 8

+

Install Umbraco 9

-

Enter your name, email and password to install Umbraco 8 with its default settings, alternatively you can customize your installation

+

Enter your name, email and password to install Umbraco 9 with its default settings, alternatively you can customize your installation

diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 8305ed5a30..9a9901394f 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -1,6 +1,7 @@ using System; using System.Data.Common; using System.Data.SqlClient; +using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -49,9 +50,6 @@ namespace Umbraco.Web.UI.BackOffice services.AddUmbracoConfiguration(_config); services.AddUmbracoRuntimeMinifier(_config); - // need to manually register this factory - DbProviderFactories.RegisterFactory(Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance); - services.AddUmbracoCore(_env, out var factory); services.AddUmbracoWebsite(); diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index 8e1e656a6f..79f194a4f9 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -48,6 +48,7 @@ +