Merge remote-tracking branch 'origin/netcore/dev' into netcore/bugfix/logging-fixing
# Conflicts: # src/Umbraco.Tests.Integration/RuntimeTests.cs # src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs # src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs
This commit is contained in:
190
src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs
Normal file
190
src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a fast <see cref="IAppCache"/> on top of HttpContext.Items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If no current HttpContext items can be found (no current HttpContext,
|
||||
/// or no Items...) then this cache acts as a pass-through and does not cache
|
||||
/// anything.</para>
|
||||
/// </remarks>
|
||||
public class GenericDictionaryRequestAppCache : FastDictionaryAppCacheBase, IRequestCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpRequestAppCache"/> class with a context, for unit tests!
|
||||
/// </summary>
|
||||
public GenericDictionaryRequestAppCache(Func<IDictionary<object, object>> requestItems) : base()
|
||||
{
|
||||
ContextItems = requestItems;
|
||||
}
|
||||
|
||||
private Func<IDictionary<object, object>> ContextItems { get; }
|
||||
|
||||
public bool IsAvailable => TryGetContextItems(out _);
|
||||
|
||||
private bool TryGetContextItems(out IDictionary<object, object> items)
|
||||
{
|
||||
items = ContextItems?.Invoke();
|
||||
return items != null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object Get(string key, Func<object> factory)
|
||||
{
|
||||
//no place to cache so just return the callback result
|
||||
if (!TryGetContextItems(out var items)) return factory();
|
||||
|
||||
key = GetCacheKey(key);
|
||||
|
||||
Lazy<object> result;
|
||||
|
||||
try
|
||||
{
|
||||
EnterWriteLock();
|
||||
result = items[key] as Lazy<object>; // null if key not found
|
||||
|
||||
// cannot create value within the lock, so if result.IsValueCreated is false, just
|
||||
// do nothing here - means that if creation throws, a race condition could cause
|
||||
// more than one thread to reach the return statement below and throw - accepted.
|
||||
|
||||
if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = SafeLazy.GetSafeLazy(factory);
|
||||
items[key] = result;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitWriteLock();
|
||||
}
|
||||
|
||||
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
|
||||
// exceptions (but try again and again) and silently eat them - however at
|
||||
// some point we have to report them - so need to re-throw here
|
||||
|
||||
// this does not throw anymore
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (value is SafeLazy.ExceptionHolder eh) eh.Exception.Throw(); // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool Set(string key, object value)
|
||||
{
|
||||
//no place to cache so just return the callback result
|
||||
if (!TryGetContextItems(out var items)) return false;
|
||||
key = GetCacheKey(key);
|
||||
try
|
||||
{
|
||||
|
||||
EnterWriteLock();
|
||||
items[key] = SafeLazy.GetSafeLazy(() => value);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
//no place to cache so just return the callback result
|
||||
if (!TryGetContextItems(out var items)) return false;
|
||||
key = GetCacheKey(key);
|
||||
try
|
||||
{
|
||||
|
||||
EnterWriteLock();
|
||||
items.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Entries
|
||||
|
||||
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
|
||||
if (!TryGetContextItems(out var items)) return Enumerable.Empty<DictionaryEntry>();
|
||||
|
||||
return items.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string s && s.StartsWith(prefix));
|
||||
}
|
||||
|
||||
protected override void RemoveEntry(string key)
|
||||
{
|
||||
if (!TryGetContextItems(out var items)) return;
|
||||
|
||||
items.Remove(key);
|
||||
}
|
||||
|
||||
protected override object GetEntry(string key)
|
||||
{
|
||||
return !TryGetContextItems(out var items) ? null : items[key];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lock
|
||||
|
||||
private const string ContextItemsLockKey = "Umbraco.Core.Cache.HttpRequestCache::LockEntered";
|
||||
|
||||
protected override void EnterReadLock() => EnterWriteLock();
|
||||
|
||||
protected override void EnterWriteLock()
|
||||
{
|
||||
if (!TryGetContextItems(out var items)) return;
|
||||
|
||||
// note: cannot keep 'entered' as a class variable here,
|
||||
// since there is one per request - so storing it within
|
||||
// ContextItems - which is locked, so this should be safe
|
||||
|
||||
var entered = false;
|
||||
Monitor.Enter(items, ref entered);
|
||||
items[ContextItemsLockKey] = entered;
|
||||
}
|
||||
|
||||
protected override void ExitReadLock() => ExitWriteLock();
|
||||
|
||||
protected override void ExitWriteLock()
|
||||
{
|
||||
if (!TryGetContextItems(out var items)) return;
|
||||
|
||||
var entered = (bool?)items[ContextItemsLockKey] ?? false;
|
||||
if (entered)
|
||||
Monitor.Exit(items);
|
||||
items.Remove(ContextItemsLockKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
if (!TryGetContextItems(out var items))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
yield return new KeyValuePair<string, object>(item.Key.ToString(), item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
7
src/Umbraco.Core/Net/NullSessionIdResolver.cs
Normal file
7
src/Umbraco.Core/Net/NullSessionIdResolver.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Net
|
||||
{
|
||||
public class NullSessionIdResolver : ISessionIdResolver
|
||||
{
|
||||
public string SessionId => null;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Infrastructure.Media;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Cache;
|
||||
@@ -351,10 +352,6 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
// register accessors for cultures
|
||||
composition.RegisterUnique<IDefaultCultureAccessor, DefaultCultureAccessor>();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Umbraco.Core.Runtime
|
||||
private IFactory _factory;
|
||||
private readonly RuntimeState _state;
|
||||
private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker;
|
||||
private readonly IRequestCache _requestCache;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IConnectionStrings _connectionStrings;
|
||||
|
||||
@@ -39,7 +40,8 @@ namespace Umbraco.Core.Runtime
|
||||
IBackOfficeInfo backOfficeInfo,
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IMainDom mainDom,
|
||||
ITypeFinder typeFinder)
|
||||
ITypeFinder typeFinder,
|
||||
IRequestCache requestCache)
|
||||
{
|
||||
IOHelper = ioHelper;
|
||||
Configs = configs;
|
||||
@@ -50,6 +52,7 @@ namespace Umbraco.Core.Runtime
|
||||
DbProviderFactoryCreator = dbProviderFactoryCreator;
|
||||
|
||||
_umbracoBootPermissionChecker = umbracoBootPermissionChecker;
|
||||
_requestCache = requestCache;
|
||||
|
||||
Logger = logger;
|
||||
MainDom = mainDom;
|
||||
@@ -110,6 +113,7 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
if (register is null) throw new ArgumentNullException(nameof(register));
|
||||
|
||||
|
||||
// create and register the essential services
|
||||
// ie the bare minimum required to boot
|
||||
|
||||
@@ -129,12 +133,19 @@ namespace Umbraco.Core.Runtime
|
||||
"Booted.",
|
||||
"Boot failed."))
|
||||
{
|
||||
Logger.Info<CoreRuntime>("Booting Core");
|
||||
|
||||
Logger.Info<CoreRuntime>("Booting site '{HostingSiteName}', app '{HostingApplicationId}', path '{HostingPhysicalPath}', server '{MachineName}'.",
|
||||
HostingEnvironment?.SiteName,
|
||||
HostingEnvironment?.ApplicationId,
|
||||
HostingEnvironment?.ApplicationPhysicalPath,
|
||||
NetworkHelper.MachineName);
|
||||
Logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
|
||||
// application environment
|
||||
ConfigureUnhandledException();
|
||||
return _factory = Configure(register, timer);
|
||||
_factory = Configure(register, timer);
|
||||
|
||||
return _factory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +162,7 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
|
||||
// run handlers
|
||||
RuntimeOptions.DoRuntimeBoot(ProfilingLogger);
|
||||
@@ -244,6 +255,13 @@ namespace Umbraco.Core.Runtime
|
||||
// create & initialize the components
|
||||
_components = _factory.GetInstance<ComponentCollection>();
|
||||
_components.Initialize();
|
||||
|
||||
|
||||
// now (and only now) is the time to switch over to perWebRequest scopes.
|
||||
// up until that point we may not have a request, and scoped services would
|
||||
// fail to resolve - but we run Initialize within a factory scope - and then,
|
||||
// here, we switch the factory to bind scopes to requests
|
||||
_factory.EnablePerWebRequestScope();
|
||||
}
|
||||
|
||||
protected virtual void ConfigureUnhandledException()
|
||||
@@ -350,7 +368,7 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
return new AppCaches(
|
||||
new DeepCloneAppCache(new ObjectCacheAppCache()),
|
||||
NoAppCache.Instance,
|
||||
_requestCache,
|
||||
new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Runtime;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Web Umbraco runtime.
|
||||
/// </summary>
|
||||
/// <remarks>On top of CoreRuntime, handles all of the web-related runtime aspects of Umbraco.</remarks>
|
||||
public class WebRuntime : CoreRuntime
|
||||
{
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebRuntime"/> class.
|
||||
/// </summary>
|
||||
public WebRuntime(
|
||||
Configs configs,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IIOHelper ioHelper,
|
||||
ILogger logger,
|
||||
IProfiler profiler,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IBackOfficeInfo backOfficeInfo,
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IMainDom mainDom,
|
||||
ITypeFinder typeFinder,
|
||||
IRequestCache requestCache,
|
||||
IUmbracoBootPermissionChecker umbracoBootPermissionChecker):
|
||||
base(configs, umbracoVersion, ioHelper, logger, profiler ,umbracoBootPermissionChecker, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, typeFinder)
|
||||
{
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IFactory Configure(IRegister register)
|
||||
{
|
||||
|
||||
var profilingLogger = new ProfilingLogger(Logger, Profiler);
|
||||
var umbracoVersion = new UmbracoVersion();
|
||||
using (var timer = profilingLogger.TraceDuration<CoreRuntime>(
|
||||
$"Booting Umbraco {umbracoVersion.SemanticVersion.ToSemanticString()}.",
|
||||
"Booted.",
|
||||
"Boot failed."))
|
||||
{
|
||||
Logger.Info<CoreRuntime>("Booting site '{HostingSiteName}', app '{HostingApplicationId}', path '{HostingPhysicalPath}', server '{MachineName}'.",
|
||||
HostingEnvironment.SiteName,
|
||||
HostingEnvironment.ApplicationId,
|
||||
HostingEnvironment.ApplicationPhysicalPath,
|
||||
NetworkHelper.MachineName);
|
||||
Logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
|
||||
var factory = base.Configure(register);
|
||||
|
||||
// now (and only now) is the time to switch over to perWebRequest scopes.
|
||||
// up until that point we may not have a request, and scoped services would
|
||||
// fail to resolve - but we run Initialize within a factory scope - and then,
|
||||
// here, we switch the factory to bind scopes to requests
|
||||
factory.EnablePerWebRequestScope();
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#region Getters
|
||||
|
||||
protected override AppCaches GetAppCaches() => new AppCaches(
|
||||
// we need to have the dep clone runtime cache provider to ensure
|
||||
// all entities are cached properly (cloned in and cloned out)
|
||||
new DeepCloneAppCache(new ObjectCacheAppCache()),
|
||||
// we need request based cache when running in web-based context
|
||||
_requestCache,
|
||||
new IsolatedCaches(type =>
|
||||
// we need to have the dep clone runtime cache provider to ensure
|
||||
// all entities are cached properly (cloned in and cloned out)
|
||||
new DeepCloneAppCache(new ObjectCacheAppCache())));
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Smidge;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Runtime;
|
||||
@@ -57,7 +59,7 @@ namespace Umbraco.Tests.Integration
|
||||
var coreRuntime = new CoreRuntime(testHelper.GetConfigs(), testHelper.GetUmbracoVersion(),
|
||||
testHelper.IOHelper, testHelper.Logger, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker,
|
||||
testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator,
|
||||
testHelper.MainDom, testHelper.GetTypeFinder());
|
||||
testHelper.MainDom, testHelper.GetTypeFinder(), NoAppCache.Instance);
|
||||
|
||||
// boot it!
|
||||
var factory = coreRuntime.Configure(umbracoContainer);
|
||||
@@ -99,7 +101,7 @@ namespace Umbraco.Tests.Integration
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, testHelper.GetLoggingConfiguration(), out _);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
@@ -138,7 +140,7 @@ namespace Umbraco.Tests.Integration
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, testHelper.GetLoggingConfiguration(), out _);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Umbraco.Tests.Integration.Testing
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, testHelper.GetLoggingConfiguration(), out _);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
|
||||
@@ -16,10 +16,10 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Runtime;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.PublishedContent;
|
||||
using Umbraco.Tests.Testing;
|
||||
@@ -47,10 +47,10 @@ namespace Umbraco.Tests.Routing
|
||||
HostingEnvironment);
|
||||
}
|
||||
|
||||
public class TestRuntime : WebRuntime
|
||||
public class TestRuntime : CoreRuntime
|
||||
{
|
||||
public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
|
||||
: base(configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), TestHelper.GetRequestCache(), new AspNetUmbracoBootPermissionChecker())
|
||||
: base(configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), NoAppCache.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Examine;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
@@ -116,7 +117,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
public class TestRuntime : CoreRuntime
|
||||
{
|
||||
public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
|
||||
:base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder())
|
||||
:base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), NoAppCache.Instance)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
var runtimeState = new RuntimeState(logger, null, umbracoVersion, backOfficeInfo);
|
||||
var configs = TestHelper.GetConfigs();
|
||||
var variationContextAccessor = TestHelper.VariationContextAccessor;
|
||||
|
||||
|
||||
|
||||
// create the register and the composition
|
||||
var register = TestHelper.GetRegister();
|
||||
@@ -84,7 +84,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo);
|
||||
|
||||
// create the core runtime and have it compose itself
|
||||
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder);
|
||||
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, NoAppCache.Instance);
|
||||
|
||||
// determine actual runtime level
|
||||
runtimeState.DetermineRuntimeLevel(databaseFactory, logger);
|
||||
@@ -278,7 +278,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo);
|
||||
|
||||
// create the core runtime and have it compose itself
|
||||
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder);
|
||||
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, NoAppCache.Instance);
|
||||
|
||||
// get the components
|
||||
// all of them?
|
||||
@@ -322,8 +322,8 @@ namespace Umbraco.Tests.Runtimes
|
||||
Assert.AreEqual(0, results.Count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core.Runtime;
|
||||
using Umbraco.Core.WebAssets;
|
||||
using Umbraco.Web.BackOffice.Controllers;
|
||||
using Umbraco.Web.Common.ActionResults;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Filters
|
||||
@@ -14,10 +12,11 @@ namespace Umbraco.Web.BackOffice.Filters
|
||||
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
|
||||
{
|
||||
// logic before action goes here
|
||||
var hostingEnvironment = context.HttpContext.RequestServices.GetService<IHostingEnvironment>();
|
||||
var serviceProvider = context.HttpContext.RequestServices;
|
||||
var hostingEnvironment = serviceProvider.GetService<IHostingEnvironment>();
|
||||
if (!hostingEnvironment.IsDebugMode)
|
||||
{
|
||||
var runtimeMinifier = context.HttpContext.RequestServices.GetService<IRuntimeMinifier>();
|
||||
var runtimeMinifier = serviceProvider.GetService<IRuntimeMinifier>();
|
||||
|
||||
if (context.Result is JavaScriptResult jsResult)
|
||||
{
|
||||
|
||||
12
src/Umbraco.Web.Common/Constants/ViewConstants.cs
Normal file
12
src/Umbraco.Web.Common/Constants/ViewConstants.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Umbraco.Web.Common.Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// constants
|
||||
/// </summary>
|
||||
internal static class ViewConstants
|
||||
{
|
||||
internal const string ViewLocation = "~/Views";
|
||||
|
||||
internal const string DataTokenCurrentViewContext = "umbraco-current-view-context";
|
||||
}
|
||||
}
|
||||
9
src/Umbraco.Web.Common/Controllers/RenderController.cs
Normal file
9
src/Umbraco.Web.Common/Controllers/RenderController.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Common.Controllers
|
||||
{
|
||||
public abstract class RenderController : Controller
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
17
src/Umbraco.Web.Common/Events/ActionExecutedEventArgs.cs
Normal file
17
src/Umbraco.Web.Common/Events/ActionExecutedEventArgs.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Common.Events
|
||||
{
|
||||
public class ActionExecutedEventArgs : EventArgs
|
||||
{
|
||||
public Controller Controller { get; set; }
|
||||
public object Model { get; set; }
|
||||
|
||||
public ActionExecutedEventArgs(Controller controller, object model)
|
||||
{
|
||||
Controller = controller;
|
||||
Model = model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
@@ -80,7 +82,17 @@ namespace Umbraco.Web.Common.Extensions
|
||||
Path.Combine(webHostEnvironment.ContentRootPath, "config\\serilog.config"),
|
||||
Path.Combine(webHostEnvironment.ContentRootPath, "config\\serilog.user.config"));
|
||||
|
||||
services.AddUmbracoCore(webHostEnvironment, umbContainer, Assembly.GetEntryAssembly(), loggingConfig, out factory);
|
||||
IHttpContextAccessor httpContextAccessor = new HttpContextAccessor();
|
||||
services.AddSingleton<IHttpContextAccessor>(httpContextAccessor);
|
||||
|
||||
var requestCache = new GenericDictionaryRequestAppCache(() => httpContextAccessor.HttpContext.Items);
|
||||
|
||||
services.AddUmbracoCore(webHostEnvironment,
|
||||
umbContainer,
|
||||
Assembly.GetEntryAssembly(),
|
||||
requestCache,
|
||||
loggingConfig,
|
||||
out factory);
|
||||
|
||||
return services;
|
||||
}
|
||||
@@ -92,6 +104,8 @@ namespace Umbraco.Web.Common.Extensions
|
||||
/// <param name="webHostEnvironment"></param>
|
||||
/// <param name="umbContainer"></param>
|
||||
/// <param name="entryAssembly"></param>
|
||||
/// <param name="requestCache"></param>
|
||||
/// <param name="httpContextAccessor"></param>
|
||||
/// <param name="loggingConfiguration"></param>
|
||||
/// <param name="factory"></param>
|
||||
/// <returns></returns>
|
||||
@@ -100,6 +114,7 @@ namespace Umbraco.Web.Common.Extensions
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
IRegister umbContainer,
|
||||
Assembly entryAssembly,
|
||||
IRequestCache requestCache,
|
||||
ILoggingConfiguration loggingConfiguration,
|
||||
out IFactory factory)
|
||||
{
|
||||
@@ -108,11 +123,15 @@ namespace Umbraco.Web.Common.Extensions
|
||||
if (container is null) throw new ArgumentNullException(nameof(container));
|
||||
if (entryAssembly is null) throw new ArgumentNullException(nameof(entryAssembly));
|
||||
|
||||
// Special case! The generic host adds a few default services but we need to manually add this one here NOW because
|
||||
// we resolve it before the host finishes configuring in the call to CreateCompositionRoot
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var configs = serviceProvider.GetService<Configs>();
|
||||
|
||||
CreateCompositionRoot(services, webHostEnvironment, loggingConfiguration, out var logger, out var configs, out var ioHelper, out var hostingEnvironment, out var backOfficeInfo, out var profiler);
|
||||
|
||||
CreateCompositionRoot(services,
|
||||
configs,
|
||||
webHostEnvironment,
|
||||
loggingConfiguration,
|
||||
out var logger, out var ioHelper, out var hostingEnvironment, out var backOfficeInfo, out var profiler);
|
||||
|
||||
var globalSettings = configs.Global();
|
||||
var umbracoVersion = new UmbracoVersion(globalSettings);
|
||||
@@ -125,7 +144,8 @@ namespace Umbraco.Web.Common.Extensions
|
||||
profiler,
|
||||
hostingEnvironment,
|
||||
backOfficeInfo,
|
||||
CreateTypeFinder(logger, profiler, webHostEnvironment, entryAssembly));
|
||||
CreateTypeFinder(logger, profiler, webHostEnvironment, entryAssembly),
|
||||
requestCache);
|
||||
|
||||
factory = coreRuntime.Configure(container);
|
||||
|
||||
@@ -142,11 +162,12 @@ namespace Umbraco.Web.Common.Extensions
|
||||
return new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(entryAssembly), runtimeHash);
|
||||
}
|
||||
|
||||
private static IRuntime GetCoreRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, Core.Logging.ILogger logger,
|
||||
private static IRuntime GetCoreRuntime(
|
||||
Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, Core.Logging.ILogger logger,
|
||||
IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo,
|
||||
ITypeFinder typeFinder)
|
||||
ITypeFinder typeFinder, IRequestCache requestCache)
|
||||
{
|
||||
var connectionStringConfig = configs.ConnectionStrings()[Constants.System.UmbracoConnectionName];
|
||||
var connectionStringConfig = configs.ConnectionStrings()[Core.Constants.System.UmbracoConnectionName];
|
||||
var dbProviderFactoryCreator = new SqlServerDbProviderFactoryCreator(
|
||||
connectionStringConfig?.ProviderName,
|
||||
DbProviderFactories.GetFactory);
|
||||
@@ -161,23 +182,34 @@ namespace Umbraco.Web.Common.Extensions
|
||||
|
||||
var mainDom = new MainDom(logger, mainDomLock);
|
||||
|
||||
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetCoreBootPermissionsChecker(),
|
||||
hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, typeFinder);
|
||||
var coreRuntime = new CoreRuntime(
|
||||
configs,
|
||||
umbracoVersion,
|
||||
ioHelper,
|
||||
logger,
|
||||
profiler,
|
||||
new AspNetCoreBootPermissionsChecker(),
|
||||
hostingEnvironment,
|
||||
backOfficeInfo,
|
||||
dbProviderFactoryCreator,
|
||||
mainDom,
|
||||
typeFinder,
|
||||
requestCache);
|
||||
|
||||
return coreRuntime;
|
||||
}
|
||||
|
||||
private static IServiceCollection CreateCompositionRoot(
|
||||
IServiceCollection services,
|
||||
Configs configs,
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
ILoggingConfiguration loggingConfiguration,
|
||||
out Core.Logging.ILogger logger, out Configs configs, out IIOHelper ioHelper, out Core.Hosting.IHostingEnvironment hostingEnvironment,
|
||||
out IBackOfficeInfo backOfficeInfo, out IProfiler profiler)
|
||||
ILoggingConfiguration loggingConfiguration,
|
||||
out Core.Logging.ILogger logger,
|
||||
out IIOHelper ioHelper,
|
||||
out Core.Hosting.IHostingEnvironment hostingEnvironment,
|
||||
out IBackOfficeInfo backOfficeInfo,
|
||||
out IProfiler profiler)
|
||||
{
|
||||
// TODO: We need to avoid this, surely there's a way? See ContainerTests.BuildServiceProvider_Before_Host_Is_Configured
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
configs = serviceProvider.GetService<Configs>();
|
||||
if (configs == null)
|
||||
throw new InvalidOperationException($"Could not resolve type {typeof(Configs)} from the container, ensure {nameof(AddUmbracoConfiguration)} is called before calling {nameof(AddUmbracoCore)}");
|
||||
|
||||
@@ -205,13 +237,13 @@ namespace Umbraco.Web.Common.Extensions
|
||||
|
||||
// Wire up all the bits that serilog needs. We need to use our own code since the Serilog ext methods don't cater to our needs since
|
||||
// we don't want to use the global serilog `Log` object and we don't have our own ILogger implementation before the HostBuilder runs which
|
||||
// is the only other option that these ext methods allow.
|
||||
// is the only other option that these ext methods allow.
|
||||
// I have created a PR to make this nicer https://github.com/serilog/serilog-extensions-hosting/pull/19 but we'll need to wait for that.
|
||||
// Also see : https://github.com/serilog/serilog-extensions-hosting/blob/dev/src/Serilog.Extensions.Hosting/SerilogHostBuilderExtensions.cs
|
||||
|
||||
services.AddSingleton<ILoggerFactory>(services => new SerilogLoggerFactory(logger.SerilogLog, false));
|
||||
|
||||
// This won't (and shouldn't) take ownership of the logger.
|
||||
// This won't (and shouldn't) take ownership of the logger.
|
||||
services.AddSingleton(logger.SerilogLog);
|
||||
|
||||
// Registered to provide two services...
|
||||
@@ -229,7 +261,7 @@ namespace Umbraco.Web.Common.Extensions
|
||||
public static IServiceCollection AddUmbracoRuntimeMinifier(this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
services.AddSmidge(configuration.GetSection(Constants.Configuration.ConfigRuntimeMinification));
|
||||
services.AddSmidge(configuration.GetSection(Core.Constants.Configuration.ConfigRuntimeMinification));
|
||||
services.AddSmidgeNuglify();
|
||||
|
||||
return services;
|
||||
@@ -260,4 +292,5 @@ namespace Umbraco.Web.Common.Extensions
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Umbraco.Web.Common.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that the request is not cached by the browser
|
||||
/// </summary>
|
||||
public class DisableBrowserCacheAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
base.OnResultExecuting(context);
|
||||
|
||||
var httpResponse = context.HttpContext.Response;
|
||||
|
||||
if (httpResponse.StatusCode != 200) return;
|
||||
|
||||
httpResponse.GetTypedHeaders().CacheControl =
|
||||
new CacheControlHeaderValue()
|
||||
{
|
||||
NoCache = true,
|
||||
MaxAge = TimeSpan.Zero,
|
||||
MustRevalidate = true,
|
||||
NoStore = true
|
||||
};
|
||||
|
||||
httpResponse.Headers[HeaderNames.LastModified] = DateTime.Now.ToString("R"); // Format RFC1123
|
||||
httpResponse.Headers[HeaderNames.Pragma] = "no-cache";
|
||||
httpResponse.Headers[HeaderNames.Expires] = new DateTime(1990, 1, 1, 0, 0, 0).ToString("R");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Umbraco.Web.Common.Constants;
|
||||
using Umbraco.Web.Common.Controllers;
|
||||
|
||||
namespace Umbraco.Web.Common.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a special filter which is required for the RTE to be able to render Partial View Macros that
|
||||
/// contain forms when the RTE value is resolved outside of an MVC view being rendered
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The entire way that we support partial view macros that contain forms isn't really great, these forms
|
||||
/// need to be executed as ChildActions so that the ModelState,ViewData,TempData get merged into that action
|
||||
/// so the form can show errors, viewdata, etc...
|
||||
/// Under normal circumstances, macros will be rendered after a ViewContext is created but in some cases
|
||||
/// developers will resolve the RTE value in the controller, in this case the Form won't be rendered correctly
|
||||
/// with merged ModelState from the controller because the special DataToken hasn't been set yet (which is
|
||||
/// normally done in the UmbracoViewPageOfModel when a real ViewContext is available.
|
||||
/// So we need to detect if the currently rendering controller is IRenderController and if so we'll ensure that
|
||||
/// this DataToken exists before the action executes in case the developer resolves an RTE value that contains
|
||||
/// a partial view macro form.
|
||||
/// </remarks>
|
||||
public class EnsurePartialViewMacroViewContextFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the custom ViewContext datatoken is set before the RenderController action is invoked,
|
||||
/// this ensures that any calls to GetPropertyValue with regards to RTE or Grid editors can still
|
||||
/// render any PartialViewMacro with a form and maintain ModelState
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
if (!(context.Controller is Controller controller)) return;
|
||||
|
||||
//ignore anything that is not IRenderController
|
||||
if (!(controller is RenderController)) return;
|
||||
|
||||
SetViewContext(context, controller);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the custom ViewContext datatoken is set after the RenderController action is invoked,
|
||||
/// this ensures that any custom ModelState that may have been added in the RenderController itself is
|
||||
/// passed onwards in case it is required when rendering a PartialViewMacro with a form
|
||||
/// </summary>
|
||||
/// <param name="context">The filter context.</param>
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
if (!(context.Controller is Controller controller)) return;
|
||||
|
||||
//ignore anything that is not IRenderController
|
||||
if (!(controller is RenderController)) return;
|
||||
|
||||
SetViewContext(context, controller);
|
||||
}
|
||||
|
||||
private void SetViewContext(ActionContext context, Controller controller)
|
||||
{
|
||||
var viewCtx = new ViewContext(
|
||||
context,
|
||||
new DummyView(),
|
||||
controller.ViewData,
|
||||
controller.TempData,
|
||||
new StringWriter(),
|
||||
new HtmlHelperOptions());
|
||||
|
||||
//set the special data token
|
||||
context.RouteData.DataTokens[ViewConstants.DataTokenCurrentViewContext] = viewCtx;
|
||||
}
|
||||
|
||||
private class DummyView : IView
|
||||
{
|
||||
public Task RenderAsync(ViewContext context)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Umbraco.Web.Common.Events;
|
||||
|
||||
namespace Umbraco.Web.Common.Filters
|
||||
{
|
||||
public class PreRenderViewActionFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
if (!(context.Controller is Controller umbController) || !(context.Result is ViewResult result))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var model = result.Model;
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var args = new ActionExecutedEventArgs(umbController, model);
|
||||
OnActionExecuted(args);
|
||||
|
||||
if (args.Model != model)
|
||||
{
|
||||
result.ViewData.Model = args.Model;
|
||||
}
|
||||
|
||||
base.OnActionExecuted(context);
|
||||
}
|
||||
|
||||
|
||||
public static event EventHandler<ActionExecutedEventArgs> ActionExecuted;
|
||||
|
||||
private static void OnActionExecuted(ActionExecutedEventArgs e)
|
||||
{
|
||||
var handler = ActionExecuted;
|
||||
handler?.Invoke(null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/Umbraco.Web.Common/Filters/StatusCodeResultAttribute.cs
Normal file
39
src/Umbraco.Web.Common/Filters/StatusCodeResultAttribute.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Web.Common.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Forces the response to have a specific http status code
|
||||
/// </summary>
|
||||
public class StatusCodeResultAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly HttpStatusCode _statusCode;
|
||||
|
||||
public StatusCodeResultAttribute(HttpStatusCode statusCode)
|
||||
{
|
||||
_statusCode = statusCode;
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
base.OnActionExecuted(context);
|
||||
|
||||
var httpContext = context.HttpContext;
|
||||
|
||||
httpContext.Response.StatusCode = (int)_statusCode;
|
||||
|
||||
var disableIisCustomErrors = httpContext.RequestServices.GetService<IWebRoutingSettings>().TrySkipIisCustomErrors;
|
||||
var statusCodePagesFeature = httpContext.Features.Get<IStatusCodePagesFeature>();
|
||||
|
||||
if (statusCodePagesFeature != null)
|
||||
{
|
||||
// if IIS Custom Errors are disabled, we won't enable the Status Code Pages
|
||||
statusCodePagesFeature.Enabled = !disableIisCustomErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Web.Common.RuntimeMinification
|
||||
public void Reset()
|
||||
{
|
||||
var version = DateTime.UtcNow.Ticks.ToString();
|
||||
_configManipulator.SaveConfigValue(Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString());
|
||||
_configManipulator.SaveConfigValue(Core.Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace Umbraco.Web.UI.BackOffice
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
app.UseStatusCodePages();
|
||||
app.UseUmbracoCore();
|
||||
app.UseUmbracoRequestLogging();
|
||||
app.UseUmbracoWebsite();
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// Migrated already to .Net Core
|
||||
public class ActionExecutedEventArgs : EventArgs
|
||||
{
|
||||
public Controller Controller { get; set; }
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/// <summary>
|
||||
/// constants
|
||||
/// </summary>
|
||||
/// Migrated already to .Net Core
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string ViewLocation = "~/Views";
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// this DataToken exists before the action executes in case the developer resolves an RTE value that contains
|
||||
/// a partial view macro form.
|
||||
/// </remarks>
|
||||
/// Migrated already to .Net Core
|
||||
internal class EnsurePartialViewMacroViewContextFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <summary>
|
||||
/// A marker interface to designate that a controller will be used for Umbraco front-end requests and/or route hijacking
|
||||
/// </summary>
|
||||
/// Migrated already to .Net Core
|
||||
public interface IRenderController : IController
|
||||
{
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <remarks>
|
||||
/// Only minifies in release mode
|
||||
/// </remarks>
|
||||
/// Migrated already to .Net Core
|
||||
public class MinifyJavaScriptResultAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// Migrated already to .Net Core
|
||||
public class PreRenderViewActionFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext filterContext)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <summary>
|
||||
/// Forces the response to have a specific http status code
|
||||
/// </summary>
|
||||
/// Migrated already to .Net Core
|
||||
internal class StatusCodeResultAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly HttpStatusCode _statusCode;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
@@ -34,10 +37,12 @@ namespace Umbraco.Web
|
||||
|
||||
var mainDom = new MainDom(logger, mainDomLock);
|
||||
|
||||
var requestCache = new HttpRequestAppCache(() => HttpContext.Current?.Items);
|
||||
var requestCache = new HttpRequestAppCache(() => HttpContext.Current != null ? HttpContext.Current.Items : null);
|
||||
var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker();
|
||||
return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom,
|
||||
GetTypeFinder(hostingEnvironment, logger, profiler), requestCache, umbracoBootPermissionChecker);
|
||||
return new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, umbracoBootPermissionChecker, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom,
|
||||
GetTypeFinder(hostingEnvironment, logger, profiler), requestCache);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user