Extracted IConfigManipulator from IConnectionStrings, and implemented a XML (legacy) and JSON version.

This commit is contained in:
Bjarke Berg
2020-03-18 19:17:51 +01:00
parent 814ab3e63f
commit 00418959f2
16 changed files with 431 additions and 236 deletions
@@ -1,17 +1,9 @@
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Composing;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using System.Configuration;
namespace Umbraco.Core.Configuration
{
public class ConnectionStrings : IConnectionStrings
{
public ConfigConnectionString this[string key]
{
get
@@ -21,94 +13,5 @@ namespace Umbraco.Core.Configuration
return new ConfigConnectionString(settings.ConnectionString, settings.ProviderName, settings.Name);
}
}
public void RemoveConnectionString(string key, IIOHelper ioHelper)
{
var fileName = ioHelper.MapPath(string.Format("{0}/web.config", ioHelper.Root));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();
var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key);
if (setting != null)
{
setting.Remove();
xml.Save(fileName, SaveOptions.DisableFormatting);
ConfigurationManager.RefreshSection("appSettings");
}
var settings = ConfigurationManager.ConnectionStrings[key];
}
/// <summary>
/// Saves the connection string as a proper .net connection string in web.config.
/// </summary>
/// <remarks>Saves the ConnectionString in the very nasty 'medium trust'-supportive way.</remarks>
/// <param name="connectionString">The connection string.</param>
/// <param name="providerName">The provider name.</param>
public void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper)
{
if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(connectionString));
if (providerName == null) throw new ArgumentNullException(nameof(providerName));
if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(providerName));
var fileSource = "web.config";
var fileName = ioHelper.MapPath(ioHelper.Root +"/" + fileSource);
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings).");
// handle configSource
var configSourceAttribute = connectionStrings.Attribute("configSource");
if (configSourceAttribute != null)
{
fileSource = configSourceAttribute.Value;
fileName = ioHelper.MapPath(ioHelper.Root + "/" + fileSource);
if (!File.Exists(fileName))
throw new Exception($"Invalid configSource \"{fileSource}\" (no such file).");
xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings).");
}
// create or update connection string
var setting = connectionStrings.Descendants("add").FirstOrDefault(s => s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName);
if (setting == null)
{
connectionStrings.Add(new XElement("add",
new XAttribute("name", Constants.System.UmbracoConnectionName),
new XAttribute("connectionString", connectionString),
new XAttribute("providerName", providerName)));
}
else
{
AddOrUpdateAttribute(setting, "connectionString", connectionString);
AddOrUpdateAttribute(setting, "providerName", providerName);
}
// save
Current.Logger.Info<ConnectionStrings>("Saving connection string to {ConfigFile}.", fileSource);
xml.Save(fileName, SaveOptions.DisableFormatting);
Current.Logger.Info<ConnectionStrings>("Saved connection string to {ConfigFile}.", fileSource);
}
private static void AddOrUpdateAttribute(XElement element, string name, string value)
{
var attribute = element.Attribute(name);
if (attribute == null)
element.Add(new XAttribute(name, value));
else
attribute.Value = value;
}
}
}
@@ -1,7 +1,8 @@
using System;
using System.Linq;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Configuration;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Configuration.Models
{
@@ -19,17 +20,5 @@ namespace Umbraco.Configuration.Models
get => new ConfigConnectionString(_configuration.GetConnectionString(key), "System.Data.SqlClient", key);
set => throw new NotImplementedException();
}
public void RemoveConnectionString(string umbracoConnectionName, IIOHelper ioHelper)
{
//TODO We need to figure out what to do here.. We cond have another config setting, that tells with file(s) to update? or should we assume appsettings.json
throw new NotImplementedException();
}
public void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper)
{
//TODO We need to figure out what to do here.. We cond have another config setting, that tells with file(s) to update? or should we assume appsettings.json
throw new NotImplementedException();
}
}
}
@@ -24,6 +24,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.2" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0" />
</ItemGroup>
@@ -0,0 +1,10 @@
using Umbraco.Core.IO;
namespace Umbraco.Core.Configuration
{
public interface IConfigManipulator
{
void RemoveConnectionString();
void SaveConnectionString(string connectionString, string providerName);
}
}
@@ -1,5 +1,3 @@
using Umbraco.Core.IO;
namespace Umbraco.Core.Configuration
{
public interface IConnectionStrings
@@ -8,8 +6,5 @@ namespace Umbraco.Core.Configuration
{
get;
}
void RemoveConnectionString(string umbracoConnectionName, IIOHelper ioHelper);
void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper);
}
}
@@ -0,0 +1,118 @@
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Composing;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Configuration
{
public class XmlConfigManipulator : IConfigManipulator
{
private readonly IIOHelper _ioHelper;
private readonly ILogger _logger;
public XmlConfigManipulator(IIOHelper ioHelper, ILogger logger)
{
_ioHelper = ioHelper;
_logger = logger;
}
public void RemoveConnectionString()
{
var key = Constants.System.UmbracoConnectionName;
var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();
var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key);
if (setting != null)
{
setting.Remove();
xml.Save(fileName, SaveOptions.DisableFormatting);
ConfigurationManager.RefreshSection("appSettings");
}
var settings = ConfigurationManager.ConnectionStrings[key];
}
/// <summary>
/// Saves the connection string as a proper .net connection string in web.config.
/// </summary>
/// <remarks>Saves the ConnectionString in the very nasty 'medium trust'-supportive way.</remarks>
/// <param name="connectionString">The connection string.</param>
/// <param name="providerName">The provider name.</param>
public void SaveConnectionString(string connectionString, string providerName)
{
if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
if (string.IsNullOrWhiteSpace(connectionString))
throw new ArgumentException("Value can't be empty or consist only of white-space characters.",
nameof(connectionString));
if (providerName == null) throw new ArgumentNullException(nameof(providerName));
if (string.IsNullOrWhiteSpace(providerName))
throw new ArgumentException("Value can't be empty or consist only of white-space characters.",
nameof(providerName));
var fileSource = "web.config";
var fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource);
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings).");
// handle configSource
var configSourceAttribute = connectionStrings.Attribute("configSource");
if (configSourceAttribute != null)
{
fileSource = configSourceAttribute.Value;
fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource);
if (!File.Exists(fileName))
throw new Exception($"Invalid configSource \"{fileSource}\" (no such file).");
xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null)
throw new Exception($"Invalid {fileSource} file (no connection strings).");
}
// create or update connection string
var setting = connectionStrings.Descendants("add").FirstOrDefault(s =>
s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName);
if (setting == null)
{
connectionStrings.Add(new XElement("add",
new XAttribute("name", Constants.System.UmbracoConnectionName),
new XAttribute("connectionString", connectionString),
new XAttribute("providerName", providerName)));
}
else
{
AddOrUpdateAttribute(setting, "connectionString", connectionString);
AddOrUpdateAttribute(setting, "providerName", providerName);
}
// save
_logger.Info<XmlConfigManipulator>("Saving connection string to {ConfigFile}.", fileSource);
xml.Save(fileName, SaveOptions.DisableFormatting);
_logger.Info<XmlConfigManipulator>("Saved connection string to {ConfigFile}.", fileSource);
}
private static void AddOrUpdateAttribute(XElement element, string name, string value)
{
var attribute = element.Attribute(name);
if (attribute == null)
element.Add(new XAttribute(name, value));
else
attribute.Value = value;
}
}
}
@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.FileProviders;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.Configuration
{
public class JsonConfigManipulator : IConfigManipulator
{
private readonly IConfiguration _configuration;
public JsonConfigManipulator(IConfiguration configuration)
{
_configuration = configuration;
}
public string UmbracoConnectionPath { get; } = $"ConnectionStrings:{ Constants.System.UmbracoConnectionName}";
public void RemoveConnectionString()
{
var provider = GetJsonConfigurationProvider(UmbracoConnectionPath);
var json = GetJson(provider);
RemoveJsonKey(json, UmbracoConnectionPath);
SaveJson(provider, json);
}
public void SaveConnectionString(string connectionString, string providerName)
{
var provider = GetJsonConfigurationProvider();
var json = GetJson(provider);
var item = GetConnectionItem(connectionString, providerName);
json.Merge(item, new JsonMergeSettings());
SaveJson(provider, json);
}
private JToken GetConnectionItem(string connectionString, string providerName)
{
JTokenWriter writer = new JTokenWriter();
writer.WriteStartObject();
writer.WritePropertyName("ConnectionStrings");
writer.WriteStartObject();
writer.WritePropertyName(Constants.System.UmbracoConnectionName);
writer.WriteValue(connectionString);
writer.WriteEndObject();
writer.WriteEndObject();
return writer.Token;
}
private static void RemoveJsonKey(JObject json, string key)
{
JToken token = json;
foreach (var propertyName in key.Split(new[] { ':' }))
{
token = CaseSelectPropertyValues(token, propertyName);
}
token?.Parent?.Remove();
}
private static void SaveJson(JsonConfigurationProvider provider, JObject json)
{
if (provider.Source.FileProvider is PhysicalFileProvider physicalFileProvider)
{
var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path);
using (var sw = new StreamWriter(jsonFilePath, false))
using (var jsonTextWriter = new JsonTextWriter(sw)
{
Formatting = Formatting.Indented,
})
{
json?.WriteTo(jsonTextWriter);
}
}
}
private static JObject GetJson(JsonConfigurationProvider provider)
{
if (provider.Source.FileProvider is PhysicalFileProvider physicalFileProvider)
{
var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path);
var serializer = new JsonSerializer();
using (var sr = new StreamReader(jsonFilePath))
using (var jsonTextReader = new JsonTextReader(sr))
{
return serializer.Deserialize<JObject>(jsonTextReader);
}
}
return null;
}
private JsonConfigurationProvider GetJsonConfigurationProvider(string requiredKey = null)
{
if (_configuration is IConfigurationRoot configurationRoot)
{
foreach (var provider in configurationRoot.Providers)
{
if(provider is JsonConfigurationProvider jsonConfigurationProvider)
{
if (requiredKey is null || provider.TryGet(requiredKey, out _))
{
return jsonConfigurationProvider;
}
}
}
}
throw new InvalidOperationException("Could not find a writable json config source");
}
/// <summary>
/// Returns the property value when case insensative
/// </summary>
/// <remarks>
/// This method is required because keys are case insensative in IConfiguration.
/// JObject[..] do not support case insensative and JObject.Property(...) do not return a new JObject.
/// </remarks>
private static JToken CaseSelectPropertyValues(JToken token, string name)
{
if (token is JObject obj)
{
foreach (var property in obj.Properties())
{
if (name is null)
return property.Value;
if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase))
return property.Value;
}
}
return null;
}
}
}
@@ -19,14 +19,16 @@ namespace Umbraco.Web.Install.InstallSteps
private readonly ILogger _logger;
private readonly IIOHelper _ioHelper;
private readonly IConnectionStrings _connectionStrings;
private readonly IConfigManipulator _configManipulator;
public DatabaseInstallStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings)
public DatabaseInstallStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings, IConfigManipulator configManipulator)
{
_databaseBuilder = databaseBuilder;
_runtime = runtime;
_logger = logger;
_ioHelper = ioHelper;
_connectionStrings = connectionStrings;
_configManipulator = configManipulator;
}
public override Task<InstallSetupResult> ExecuteAsync(object model)
@@ -43,7 +45,7 @@ namespace Umbraco.Web.Install.InstallSteps
if (result.RequiresUpgrade == false)
{
HandleConnectionStrings(_logger, _ioHelper, _connectionStrings);
HandleConnectionStrings(_logger, _ioHelper, _connectionStrings, _configManipulator);
return Task.FromResult<InstallSetupResult>(null);
}
@@ -54,7 +56,7 @@ namespace Umbraco.Web.Install.InstallSteps
}));
}
internal static void HandleConnectionStrings(ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings)
internal static void HandleConnectionStrings(ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings, IConfigManipulator configManipulator)
{
@@ -65,7 +67,7 @@ namespace Umbraco.Web.Install.InstallSteps
// Remove legacy umbracoDbDsn configuration setting if it exists and connectionstring also exists
if (databaseSettings != null)
{
connectionStrings.RemoveConnectionString(Constants.System.UmbracoConnectionName, ioHelper);
configManipulator.RemoveConnectionString();
}
else
{
@@ -23,8 +23,17 @@ namespace Umbraco.Web.Install.InstallSteps
private readonly IGlobalSettings _globalSettings;
private readonly IConnectionStrings _connectionStrings;
private readonly IIOHelper _ioHelper;
private readonly IConfigManipulator _configManipulator;
public DatabaseUpgradeStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IUmbracoVersion umbracoVersion, IGlobalSettings globalSettings, IConnectionStrings connectionStrings, IIOHelper ioHelper)
public DatabaseUpgradeStep(
DatabaseBuilder databaseBuilder,
IRuntimeState runtime,
ILogger logger,
IUmbracoVersion umbracoVersion,
IGlobalSettings globalSettings,
IConnectionStrings connectionStrings,
IIOHelper ioHelper,
IConfigManipulator configManipulator)
{
_databaseBuilder = databaseBuilder;
_runtime = runtime;
@@ -33,6 +42,7 @@ namespace Umbraco.Web.Install.InstallSteps
_globalSettings = globalSettings;
_connectionStrings = connectionStrings ?? throw new ArgumentNullException(nameof(connectionStrings));
_ioHelper = ioHelper;
_configManipulator = configManipulator;
}
public override Task<InstallSetupResult> ExecuteAsync(object model)
@@ -55,7 +65,7 @@ namespace Umbraco.Web.Install.InstallSteps
throw new InstallException("The database failed to upgrade. ERROR: " + result.Message);
}
DatabaseInstallStep.HandleConnectionStrings(_logger, _ioHelper, _connectionStrings);
DatabaseInstallStep.HandleConnectionStrings(_logger, _ioHelper, _connectionStrings, _configManipulator);
}
return Task.FromResult<InstallSetupResult>(null);
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Migrations.Install
private readonly IIOHelper _ioHelper;
private readonly IUmbracoVersion _umbracoVersion;
private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator;
private readonly IConnectionStrings _connectionStrings;
private readonly IConfigManipulator _configManipulator;
private DatabaseSchemaResult _databaseSchemaValidationResult;
@@ -46,7 +46,7 @@ namespace Umbraco.Core.Migrations.Install
IIOHelper ioHelper,
IUmbracoVersion umbracoVersion,
IDbProviderFactoryCreator dbProviderFactoryCreator,
IConnectionStrings connectionStrings)
IConfigManipulator configManipulator)
{
_scopeProvider = scopeProvider;
_globalSettings = globalSettings;
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Migrations.Install
_ioHelper = ioHelper;
_umbracoVersion = umbracoVersion;
_dbProviderFactoryCreator = dbProviderFactoryCreator;
_connectionStrings = connectionStrings;
_configManipulator = configManipulator;
}
#region Status
@@ -146,7 +146,7 @@ namespace Umbraco.Core.Migrations.Install
private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper)
{
_connectionStrings.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe, ioHelper);
_configManipulator.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe);
var path = Path.Combine(ioHelper.GetRootDirectorySafe(), "App_Data", "Umbraco.sdf");
if (File.Exists(path) == false)
@@ -169,7 +169,7 @@ namespace Umbraco.Core.Migrations.Install
{
const string providerName = Constants.DbProviderNames.SqlServer;
_connectionStrings.SaveConnectionString(connectionString, providerName, _ioHelper);
_configManipulator.SaveConnectionString(connectionString, providerName);
_databaseFactory.Configure(connectionString, providerName);
}
@@ -185,7 +185,7 @@ namespace Umbraco.Core.Migrations.Install
{
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out var providerName);
_connectionStrings.SaveConnectionString(connectionString, providerName, _ioHelper);
_configManipulator.SaveConnectionString(connectionString, providerName);
_databaseFactory.Configure(connectionString, providerName);
}
@@ -216,7 +216,7 @@ namespace Umbraco.Core.Migrations.Install
public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName)
{
var connectionString = GetIntegratedSecurityDatabaseConnectionString(server, databaseName);
_connectionStrings.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer, _ioHelper);
_configManipulator.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer);
_databaseFactory.Configure(connectionString, Constants.DbProviderNames.SqlServer);
}
@@ -175,6 +175,7 @@ namespace Umbraco.Core.Runtime
// Grid config is not a real config file as we know them
composition.RegisterUnique<IGridConfig, GridConfig>();
}
}
}
@@ -11,6 +11,8 @@
<PackageReference Include="LightInject.Annotation" Version="1.1.0" />
<PackageReference Include="Markdown" Version="2.2.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.2" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" />
<PackageReference Include="MiniProfiler.Shared" Version="4.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
@@ -8,7 +8,6 @@ using Umbraco.Configuration;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Logging.Serilog;
@@ -24,7 +23,6 @@ namespace Umbraco.Web.BackOffice.AspNetCore
var configsFactory = new AspNetCoreConfigsFactory(configuration);
var configs = configsFactory.Create();
services.AddSingleton(configs);
return services;
@@ -39,6 +37,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
var webHostEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
var hostApplicationLifetime = serviceProvider.GetService<IHostApplicationLifetime>();
var configs = serviceProvider.GetService<Configs>();
services.CreateCompositionRoot(
@@ -62,10 +61,13 @@ namespace Umbraco.Web.BackOffice.AspNetCore
var coreDebug = configs.CoreDebug();
var globalSettings = configs.Global();
var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime);
var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment,
httpContextAccessor, hostApplicationLifetime);
var ioHelper = new IOHelper(hostingEnvironment, globalSettings);
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetCoreSessionIdResolver(httpContextAccessor), () => services.BuildServiceProvider().GetService<IRequestCache>(), coreDebug, ioHelper, new AspNetCoreMarchal());
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment,
new AspNetCoreSessionIdResolver(httpContextAccessor),
() => services.BuildServiceProvider().GetService<IRequestCache>(), coreDebug, ioHelper,
new AspNetCoreMarchal());
var backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings);
var profiler = new LogProfiler(logger);
@@ -1,4 +1,7 @@
{
"ConnectionStrings": {
"umbracoDbDSN": ""
},
"Logging": {
"LogLevel": {
"Default": "Information",
+100 -102
View File
@@ -1,105 +1,103 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Umbraco": {
"CMS": {
"Imaging": {
"Resize": {
"MaxWidth": 5000,
"MaxHeight": 5000
},
"CacheFolder" : "../App_Data/Cache",
"Cache": {
"Folder": "../App_Data/Cache",
"MaxBrowserCacheDays": 7,
"MaxCacheDays": 365,
"CachedNameLength": 8
}
},
"HealthChecks": {
"DisabledChecks": [
{
"id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF",
"disabledBy": 1,
"disabledOn": "2020-03-15 19:19:10"
}
],
"NotificationSettings": {
"Enabled": true,
"FirstRunTime" : "",
"PeriodInHours": 24,
"NotificationMethods": {
"Email": {
"Enabled" : true,
"Verbosity" : "Summary",
"Settings": {
"RecipientEmail": ""
}
}
},
"DisabledChecks": [
{
"id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF",
"disabledBy": 1,
"disabledOn": "2020-03-15 19:19:10"
}
]
}
},
"Tours": {
"EnableTours": true
},
"Core": {
"Debug": {
}
},
"Content": {
"Errors": {
"Error404" : {
"default": "1047",
"en-US":"$site/error [@name = 'error']",
"en-UK" : "8560867F-B88F-4C74-A9A4-679D8E5B3BFC"
}
}
},
"RequestHandler": {
"AddTrailingSlash": true,
"CharCollection": {
" ": "-",
"\"":"",
"'":"",
"%":"",
".":"",
";":"",
"/":"",
"\\":"",
":":"",
"#":"",
"+":"plus",
"*":"star",
"&":"",
"?":"",
"æ":"ae",
"ø":"oe",
"å":"aa",
"ä":"ae",
"ö":"oe",
"ü":"ue",
"ß":"ss",
"|":"-",
"<":"",
">":""
}
}
},
"ConnectionStrings": {
"umbracoDbDSN": ""
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Umbraco": {
"CMS": {
"Imaging": {
"Resize": {
"MaxWidth": 5000,
"MaxHeight": 5000
},
"Cache": {
"Folder": "../App_Data/Cache",
"MaxBrowserCacheDays": 7,
"MaxCacheDays": 365,
"CachedNameLength": 8
}
},
"HealthChecks": {
"DisabledChecks": [
{
"id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF",
"disabledBy": 1,
"disabledOn": "2020-03-15 19:19:10"
}
],
"NotificationSettings": {
"Enabled": true,
"FirstRunTime": "",
"PeriodInHours": 24,
"NotificationMethods": {
"Email": {
"Enabled": true,
"Verbosity": "Summary",
"Settings": {
"RecipientEmail": ""
}
}
},
"DisabledChecks": [
{
"id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF",
"disabledBy": 1,
"disabledOn": "2020-03-15 19:19:10"
}
]
}
},
"Tours": {
"EnableTours": true
},
"Core": {
"Debug": {}
},
"Content": {
"Errors": {
"Error404": {
"default": "1047",
"en-US": "$site/error [@name = 'error']",
"en-UK": "8560867F-B88F-4C74-A9A4-679D8E5B3BFC"
}
}
},
"RequestHandler": {
"AddTrailingSlash": true,
"CharCollection": {
" ": "-",
"\"": "",
"'": "",
"%": "",
".": "",
";": "",
"/": "",
"\\": "",
":": "",
"#": "",
"+": "plus",
"*": "star",
"&": "",
"?": "",
"æ": "ae",
"ø": "oe",
"å": "aa",
"ä": "ae",
"ö": "oe",
"ü": "ue",
"ß": "ss",
"|": "-",
"<": "",
">": ""
}
}
}
}
}
@@ -5,6 +5,7 @@ using Microsoft.AspNet.SignalR;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Cookie;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Events;
@@ -290,6 +291,9 @@ namespace Umbraco.Web.Runtime
// replace with web implementation
composition.RegisterUnique<IPublishedSnapshotRebuilder, Migrations.PostMigrations.PublishedSnapshotRebuilder>();
// Config manipulator
composition.RegisterUnique<IConfigManipulator, XmlConfigManipulator>();
}
}
}