Conflicts: build/UmbracoVersion.txt src/Umbraco.Core/ApplicationContext.cs src/Umbraco.Core/Configuration/UmbracoConfig.cs src/Umbraco.Core/Configuration/UmbracoVersion.cs src/Umbraco.Core/CoreBootManager.cs src/Umbraco.Core/DatabaseContext.cs src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs src/Umbraco.Core/Manifest/ManifestParser.cs src/Umbraco.Core/Models/DataTypeDefinition.cs src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs src/Umbraco.Core/Persistence/Factories/MemberTypeFactory.cs src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/AlterSyntaxBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Column/CreateColumnBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Table/CreateTableBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/ExecuteBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteCodeStatementExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteSqlStatementExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/InsertBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs src/Umbraco.Core/Persistence/Migrations/Syntax/Update/UpdateBuilder.cs src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroTable.cs src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs src/Umbraco.Core/Persistence/Repositories/TagRepository.cs src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs src/Umbraco.Core/Persistence/RepositoryFactory.cs src/Umbraco.Core/Persistence/UmbracoDatabase.cs src/Umbraco.Core/PropertyEditors/IPropertyEditorValueConverter.cs src/Umbraco.Core/PropertyEditors/PropertyEditor.cs src/Umbraco.Core/PropertyEditors/PropertyEditorResolver.cs src/Umbraco.Core/Services/ContentService.cs src/Umbraco.Core/Services/ContentTypeService.cs src/Umbraco.Core/Services/DataTypeService.cs src/Umbraco.Core/Services/EntityService.cs src/Umbraco.Core/Services/LocalizationService.cs src/Umbraco.Core/Services/MacroService.cs src/Umbraco.Core/Services/MediaService.cs src/Umbraco.Core/Services/MemberGroupService.cs src/Umbraco.Core/Services/MemberService.cs src/Umbraco.Core/Services/MemberTypeService.cs src/Umbraco.Core/Services/PackagingService.cs src/Umbraco.Core/Services/ServerRegistrationService.cs src/Umbraco.Core/Services/ServiceContext.cs src/Umbraco.Core/Services/TagService.cs src/Umbraco.Core/Services/UserService.cs src/Umbraco.Core/Strings/DefaultShortStringHelper.cs src/Umbraco.Core/Sync/ConfigServerRegistrar.cs src/Umbraco.Core/Sync/DatabaseServerMessenger.cs src/Umbraco.Core/Umbraco.Core.csproj src/Umbraco.Core/UmbracoApplicationBase.cs src/Umbraco.Core/packages.config src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs src/Umbraco.Tests/Macros/MacroTests.cs src/Umbraco.Tests/Manifest/ManifestParserTests.cs src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs src/Umbraco.Tests/Migrations/MigrationRunnerTests.cs src/Umbraco.Tests/Migrations/Stubs/FiveZeroMigration.cs src/Umbraco.Tests/Migrations/Stubs/FourElevenMigration.cs src/Umbraco.Tests/Migrations/Stubs/SixZeroMigration1.cs src/Umbraco.Tests/Migrations/Stubs/SixZeroMigration2.cs src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs src/Umbraco.Tests/Mvc/UmbracoViewPageTests.cs src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs src/Umbraco.Tests/Persistence/DatabaseContextTests.cs src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/ServerRegistrationRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs src/Umbraco.Tests/Services/ContentServiceTests.cs src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs src/Umbraco.Tests/Umbraco.Tests.csproj src/Umbraco.Web.UI/Umbraco.Web.UI.csproj src/Umbraco.Web.UI/config/ClientDependency.config src/Umbraco.Web.UI/packages.config src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs src/Umbraco.Web.UI/umbraco/plugins/tinymce3/insertImage.aspx src/Umbraco.Web.UI/umbraco/settings/EditNodeTypeNew.aspx.cs src/Umbraco.Web/BatchedDatabaseServerMessenger.cs src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs src/Umbraco.Web/Cache/DistributedCacheExtensions.cs src/Umbraco.Web/Editors/AuthenticationController.cs src/Umbraco.Web/Editors/BackOfficeController.cs src/Umbraco.Web/Install/InstallSteps/DatabaseInstallStep.cs src/Umbraco.Web/Install/InstallSteps/DatabaseUpgradeStep.cs src/Umbraco.Web/Media/ThumbnailProviders/ThumbnailProvidersResolver.cs src/Umbraco.Web/Mvc/DefaultRenderMvcControllerResolver.cs src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs src/Umbraco.Web/PropertyEditors/FolderBrowserPropertyEditor.cs src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs src/Umbraco.Web/Trees/MediaTreeController.cs src/Umbraco.Web/Trees/MemberTreeController.cs src/Umbraco.Web/Umbraco.Web.csproj src/Umbraco.Web/UmbracoApplication.cs src/Umbraco.Web/UmbracoModule.cs src/Umbraco.Web/WebBootManager.cs src/Umbraco.Web/packages.config src/Umbraco.Web/umbraco.presentation/content.cs src/Umbraco.Web/umbraco.presentation/keepAliveService.cs src/Umbraco.Web/umbraco.presentation/macro.cs src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadDictionary.cs src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentControl.cs src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/ImageViewer.ascx.cs src/Umbraco.Web/umbraco.presentation/umbraco/controls/Images/UploadMediaImage.ascx.cs src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/imageViewer.aspx.cs src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMemberType.aspx.cs src/Umbraco.Web/umbraco.presentation/umbraco/plugins/tinymce3/insertImage.aspx src/Umbraco.Web/umbraco.presentation/umbraco/settings/EditNodeTypeNew.aspx.cs src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/MediaExtensions.cs src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/uQuery.cs src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs src/Umbraco.Web/umbraco.presentation/umbraco/webService.asmx.cs src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs src/UmbracoExamine/UmbracoContentIndexer.cs src/UmbracoExamine/UmbracoMemberIndexer.cs src/umbraco.MacroEngines/RazorCore/UmbracoCultureDictionary.cs src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs src/umbraco.MacroEngines/RazorDynamicNode/ExtensionMethods.cs src/umbraco.MacroEngines/app.config src/umbraco.MacroEngines/packages.config src/umbraco.MacroEngines/umbraco.MacroEngines.csproj src/umbraco.businesslogic/UmbracoSettings.cs src/umbraco.cms/businesslogic/Content.cs src/umbraco.cms/businesslogic/datatype/DataTypeDefinition.cs src/umbraco.cms/businesslogic/datatype/DefaultPreValueEditor.cs src/umbraco.cms/businesslogic/datatype/FileHandlerData.cs src/umbraco.cms/businesslogic/translation/Translation.cs src/umbraco.cms/businesslogic/web/Document.cs src/umbraco.cms/packages.config src/umbraco.editorControls/DefaultPrevalueEditor.cs src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.Designer.cs src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.resx src/umbraco.editorControls/MultiNodeTreePicker/MNTP_DataType.cs src/umbraco.editorControls/app.config src/umbraco.editorControls/macrocontainer/PrevalueEditor.cs src/umbraco.editorControls/packages.config src/umbraco.editorControls/textfieldmultiple/textfieldMultipleDataType.cs src/umbraco.editorControls/umbraco.editorControls.csproj src/umbraco.editorControls/uploadfield/uploadField.cs src/umbraco.editorControls/userControlWrapper/usercontrolPrevalueEditor.cs src/umbraco.providers/app.config
545 lines
26 KiB
C#
545 lines
26 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.Configuration;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Web;
|
|
using System.Web.Configuration;
|
|
using System.Web.Http;
|
|
using System.Web.Http.Dispatcher;
|
|
using System.Web.Mvc;
|
|
using System.Web.Routing;
|
|
using ClientDependency.Core.Config;
|
|
using Examine;
|
|
using Examine.Config;
|
|
using umbraco;
|
|
using Umbraco.Core;
|
|
using Umbraco.Core.Configuration;
|
|
using Umbraco.Core.Dictionary;
|
|
using Umbraco.Core.LightInject;
|
|
using Umbraco.Core.Logging;
|
|
using Umbraco.Core.Macros;
|
|
using Umbraco.Core.ObjectResolution;
|
|
using Umbraco.Core.Profiling;
|
|
using Umbraco.Core.PropertyEditors;
|
|
using Umbraco.Core.PropertyEditors.ValueConverters;
|
|
using Umbraco.Core.Sync;
|
|
using Umbraco.Web.Dictionary;
|
|
using Umbraco.Web.Install;
|
|
using Umbraco.Web.LightInject;
|
|
using Umbraco.Web.Macros;
|
|
using Umbraco.Web.Media;
|
|
using Umbraco.Web.Media.ThumbnailProviders;
|
|
using Umbraco.Web.Models;
|
|
using Umbraco.Web.Mvc;
|
|
using Umbraco.Web.PropertyEditors;
|
|
using Umbraco.Web.PropertyEditors.ValueConverters;
|
|
using Umbraco.Web.PublishedCache;
|
|
using Umbraco.Web.PublishedCache.XmlPublishedCache;
|
|
using Umbraco.Web.Routing;
|
|
using Umbraco.Web.Security;
|
|
using Umbraco.Web.Scheduling;
|
|
using Umbraco.Web.UI.JavaScript;
|
|
using Umbraco.Web.WebApi;
|
|
using umbraco.BusinessLogic;
|
|
using Umbraco.Core.Persistence;
|
|
using Umbraco.Core.Persistence.UnitOfWork;
|
|
using Umbraco.Core.Publishing;
|
|
using Umbraco.Core.Services;
|
|
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
|
|
using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine;
|
|
using TypeHelper = Umbraco.Core.TypeHelper;
|
|
using Umbraco.Core.LightInject;
|
|
|
|
|
|
namespace Umbraco.Web
|
|
{
|
|
/// <summary>
|
|
/// A bootstrapper for the Umbraco application which initializes all objects including the Web portion of the application
|
|
/// </summary>
|
|
public class WebBootManager : CoreBootManager
|
|
{
|
|
private readonly bool _isForTesting;
|
|
//NOTE: see the Initialize method for what this is used for
|
|
private readonly List<IIndexer> _indexesToRebuild = new List<IIndexer>();
|
|
|
|
public WebBootManager(UmbracoApplicationBase umbracoApplication)
|
|
: base(umbracoApplication)
|
|
{
|
|
_isForTesting = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor for unit tests, ensures some resolvers are not initialized
|
|
/// </summary>
|
|
/// <param name="umbracoApplication"></param>
|
|
/// <param name="logger"></param>
|
|
/// <param name="isForTesting"></param>
|
|
internal WebBootManager(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger, bool isForTesting)
|
|
: base(umbracoApplication, logger)
|
|
{
|
|
_isForTesting = isForTesting;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and returns the service context for the app
|
|
/// </summary>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="dbFactory"></param>
|
|
/// <returns></returns>
|
|
protected override ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
|
|
{
|
|
//use a request based messaging factory
|
|
var evtMsgs = new RequestLifespanMessagesFactory(new SingletonUmbracoContextAccessor());
|
|
return new ServiceContext(
|
|
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
|
|
new PetaPocoUnitOfWorkProvider(dbFactory),
|
|
new FileUnitOfWorkProvider(),
|
|
new PublishingStrategy(evtMsgs, ProfilingLogger.Logger),
|
|
ApplicationCache,
|
|
ProfilingLogger.Logger,
|
|
evtMsgs);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize objects before anything during the boot cycle happens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override IBootManager Initialize()
|
|
{
|
|
//This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
|
|
// when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
|
|
// event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
|
|
// it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
|
|
// boot process has completed. It's a hack but it works.
|
|
ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup;
|
|
|
|
base.Initialize();
|
|
|
|
//setup mvc and webapi services
|
|
SetupMvcAndWebApi();
|
|
|
|
// Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK]
|
|
ClientDependency.Core.CompositeFiles.Providers.XmlFileMapper.FileMapVirtualFolder = "~/App_Data/TEMP/ClientDependency";
|
|
ClientDependency.Core.CompositeFiles.Providers.BaseCompositeFileProcessingProvider.UrlTypeDefault = ClientDependency.Core.CompositeFiles.Providers.CompositeUrlType.Base64QueryStrings;
|
|
|
|
var section = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
|
|
if (section != null)
|
|
{
|
|
//set the max url length for CDF to be the smallest of the max query length, max request length
|
|
ClientDependency.Core.CompositeFiles.CompositeDependencyHandler.MaxHandlerUrlLength = Math.Min(section.MaxQueryStringLength, section.MaxRequestLength);
|
|
}
|
|
|
|
//Register a custom renderer - used to process property editor dependencies
|
|
var renderer = new DependencyPathRenderer();
|
|
renderer.Initialize("Umbraco.DependencyPathRenderer", new NameValueCollection
|
|
{
|
|
{ "compositeFileHandlerPath", ClientDependencySettings.Instance.CompositeFileHandlerPath }
|
|
});
|
|
ClientDependencySettings.Instance.MvcRendererCollection.Add(renderer);
|
|
|
|
// Disable the X-AspNetMvc-Version HTTP Header
|
|
MvcHandler.DisableMvcResponseHeader = true;
|
|
|
|
InstallHelper insHelper = new InstallHelper(UmbracoContext.Current);
|
|
insHelper.DeleteLegacyInstaller();
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override this method in order to ensure that the UmbracoContext is also created, this can only be
|
|
/// created after resolution is frozen!
|
|
/// </summary>
|
|
protected override void FreezeResolution()
|
|
{
|
|
base.FreezeResolution();
|
|
|
|
//before we do anything, we'll ensure the umbraco context
|
|
//see: http://issues.umbraco.org/issue/U4-1717
|
|
var httpContext = new HttpContextWrapper(UmbracoApplication.Context);
|
|
UmbracoContext.EnsureContext(
|
|
httpContext,
|
|
ApplicationContext,
|
|
new WebSecurity(httpContext, ApplicationContext),
|
|
UmbracoConfig.For.UmbracoSettings(),
|
|
UrlProviderResolver.Current.Providers,
|
|
false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensure the current profiler is the web profiler
|
|
/// </summary>
|
|
protected override IProfiler CreateProfiler()
|
|
{
|
|
return new WebProfiler();
|
|
/// Ensure that the OnApplicationStarted methods of the IApplicationEvents are called
|
|
/// </summary>
|
|
/// <param name="afterComplete"></param>
|
|
/// <returns></returns>
|
|
public override IBootManager Complete(Action<ApplicationContext> afterComplete)
|
|
{
|
|
//Wrap viewengines in the profiling engine
|
|
WrapViewEngines(ViewEngines.Engines);
|
|
|
|
//set routes
|
|
CreateRoutes();
|
|
|
|
base.Complete(afterComplete);
|
|
|
|
//Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
|
|
// (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
|
|
// initialize during startup, in which case we want it to rebuild the indexes itself.
|
|
ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
|
|
if (_indexesToRebuild.Any())
|
|
{
|
|
foreach (var indexer in _indexesToRebuild)
|
|
{
|
|
indexer.RebuildIndex();
|
|
}
|
|
}
|
|
|
|
//Now ensure webapi is initialized after everything
|
|
GlobalConfiguration.Configuration.EnsureInitialized();
|
|
|
|
return this;
|
|
}
|
|
|
|
internal static void WrapViewEngines(IList<IViewEngine> viewEngines)
|
|
{
|
|
if (viewEngines == null || viewEngines.Count == 0) return;
|
|
|
|
var originalEngines = viewEngines.Select(e => e).ToArray();
|
|
viewEngines.Clear();
|
|
foreach (var engine in originalEngines)
|
|
{
|
|
var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine(engine);
|
|
viewEngines.Add(wrappedEngine);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the application cache based on the HttpRuntime cache
|
|
/// </summary>
|
|
protected override CacheHelper CreateApplicationCache()
|
|
{
|
|
//create a web-based cache helper
|
|
return new CacheHelper();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the routes
|
|
/// </summary>
|
|
protected internal void CreateRoutes()
|
|
{
|
|
var umbracoPath = GlobalSettings.UmbracoMvcArea;
|
|
|
|
//Create the front-end route
|
|
var defaultRoute = RouteTable.Routes.MapRoute(
|
|
"Umbraco_default",
|
|
umbracoPath + "/RenderMvc/{action}/{id}",
|
|
new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
|
|
);
|
|
defaultRoute.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory());
|
|
|
|
//register install routes
|
|
RouteTable.Routes.RegisterArea<UmbracoInstallArea>();
|
|
|
|
//register all back office routes
|
|
RouteTable.Routes.RegisterArea<BackOfficeArea>();
|
|
|
|
//plugin controllers must come first because the next route will catch many things
|
|
RoutePluginControllers();
|
|
}
|
|
|
|
private void RoutePluginControllers()
|
|
{
|
|
var umbracoPath = GlobalSettings.UmbracoMvcArea;
|
|
|
|
//we need to find the plugin controllers and route them
|
|
var pluginControllers =
|
|
SurfaceControllerResolver.Current.RegisteredSurfaceControllers.Concat(
|
|
UmbracoApiControllerResolver.Current.RegisteredUmbracoApiControllers).ToArray();
|
|
|
|
//local controllers do not contain the attribute
|
|
var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
|
|
foreach (var s in localControllers)
|
|
{
|
|
if (TypeHelper.IsTypeAssignableFrom<SurfaceController>(s))
|
|
{
|
|
RouteLocalSurfaceController(s, umbracoPath);
|
|
}
|
|
else if (TypeHelper.IsTypeAssignableFrom<UmbracoApiController>(s))
|
|
{
|
|
RouteLocalApiController(s, umbracoPath);
|
|
}
|
|
}
|
|
|
|
//need to get the plugin controllers that are unique to each area (group by)
|
|
var pluginSurfaceControlleres = pluginControllers.Where(x => !PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
|
|
var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName);
|
|
//loop through each area defined amongst the controllers
|
|
foreach (var g in groupedAreas)
|
|
{
|
|
//create an area for the controllers (this will throw an exception if all controllers are not in the same area)
|
|
var pluginControllerArea = new PluginControllerArea(g.Select(PluginController.GetMetadata));
|
|
//register it
|
|
RouteTable.Routes.RegisterArea(pluginControllerArea);
|
|
}
|
|
}
|
|
|
|
private void RouteLocalApiController(Type controller, string umbracoPath)
|
|
{
|
|
var meta = PluginController.GetMetadata(controller);
|
|
|
|
//url to match
|
|
var routePath = meta.IsBackOffice == false
|
|
? umbracoPath + "/Api/" + meta.ControllerName + "/{action}/{id}"
|
|
: umbracoPath + "/BackOffice/Api/" + meta.ControllerName + "/{action}/{id}";
|
|
|
|
var route = RouteTable.Routes.MapHttpRoute(
|
|
string.Format("umbraco-{0}-{1}", "api", meta.ControllerName),
|
|
routePath,
|
|
new { controller = meta.ControllerName, id = UrlParameter.Optional },
|
|
new[] { meta.ControllerNamespace });
|
|
//web api routes don't set the data tokens object
|
|
if (route.DataTokens == null)
|
|
{
|
|
route.DataTokens = new RouteValueDictionary();
|
|
}
|
|
route.DataTokens.Add("umbraco", "api"); //ensure the umbraco token is set
|
|
}
|
|
|
|
private void RouteLocalSurfaceController(Type controller, string umbracoPath)
|
|
{
|
|
var meta = PluginController.GetMetadata(controller);
|
|
var route = RouteTable.Routes.MapRoute(
|
|
string.Format("umbraco-{0}-{1}", "surface", meta.ControllerName),
|
|
umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match
|
|
new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
|
|
new[] { meta.ControllerNamespace }); //look in this namespace to create the controller
|
|
route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set
|
|
route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace!
|
|
//make it use our custom/special SurfaceMvcHandler
|
|
route.RouteHandler = new SurfaceRouteHandler();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to customize the IoC container
|
|
/// </summary>
|
|
/// <param name="container"></param>
|
|
internal override void ConfigureServices(ServiceContainer container)
|
|
{
|
|
base.ConfigureServices(container);
|
|
|
|
//IoC setup for LightInject for mvc/webapi
|
|
Container.EnableMvc();
|
|
Container.RegisterMvcControllers(PluginManager);
|
|
container.EnablePerWebRequestScope();
|
|
container.EnableWebApi(GlobalConfiguration.Configuration);
|
|
container.RegisterApiControllers(PluginManager);
|
|
|
|
//register other services
|
|
container.Register<IPublishedContentCache, PublishedContentCache>();
|
|
container.Register<IPublishedMediaCache, PublishedMediaCache>();
|
|
//no need to declare as per request, currently we manage it's lifetime as the singleton
|
|
container.Register<UmbracoContext>(factory => UmbracoContext.Current);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes all web based and core resolves
|
|
/// </summary>
|
|
protected override void InitializeResolvers()
|
|
{
|
|
base.InitializeResolvers();
|
|
|
|
XsltExtensionsResolver.Current = new XsltExtensionsResolver(ServiceProvider, ProfilingLogger.Logger, () => PluginManager.ResolveXsltExtensions());
|
|
|
|
//set the default RenderMvcController
|
|
DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController));
|
|
|
|
//Override the default server messenger, we need to check if the legacy dist calls is enabled, if that is the
|
|
// case, then we'll set the default messenger to be the old one, otherwise we'll set it to the db messenger
|
|
// which will always be on.
|
|
if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled)
|
|
{
|
|
//set the legacy one by default - this maintains backwards compat
|
|
ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() =>
|
|
{
|
|
//we should not proceed to change this if the app/database is not configured since there will
|
|
// be no user, plus we don't need to have server messages sent if this is the case.
|
|
if (ApplicationContext.IsConfigured && ApplicationContext.DatabaseContext.IsDatabaseConfigured)
|
|
{
|
|
//disable if they are not enabled
|
|
if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var user = ApplicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId);
|
|
return new Tuple<string, string>(user.Username, user.RawPasswordValue);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
ProfilingLogger.Logger.Error<WebBootManager>("An error occurred trying to set the IServerMessenger during application startup", e);
|
|
return null;
|
|
}
|
|
}
|
|
ProfilingLogger.Logger.Warn<WebBootManager>("Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured");
|
|
return null;
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
|
|
// NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
|
|
// on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty
|
|
// this callback is used below for the DatabaseServerMessenger startup options
|
|
Action rebuildIndexes = () =>
|
|
{
|
|
//If the developer has explicitly opted out of rebuilding indexes on startup then we
|
|
// should adhere to that and not do it, this means that if they are load balancing things will be
|
|
// out of sync if they are auto-scaling but there's not much we can do about that.
|
|
if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
|
|
|
|
if (_indexesToRebuild.Any())
|
|
{
|
|
var otherIndexes = ExamineManager.Instance.IndexProviderCollection.Except(_indexesToRebuild);
|
|
foreach (var otherIndex in otherIndexes)
|
|
{
|
|
otherIndex.RebuildIndex();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//rebuild them all
|
|
ExamineManager.Instance.RebuildIndex();
|
|
}
|
|
};
|
|
|
|
ServerMessengerResolver.Current.SetServerMessenger(new BatchedDatabaseServerMessenger(
|
|
ApplicationContext,
|
|
true,
|
|
//Default options for web including the required callbacks to build caches
|
|
new DatabaseServerMessengerOptions
|
|
{
|
|
//These callbacks will be executed if the server has not been synced
|
|
// (i.e. it is a new server or the lastsynced.txt file has been removed)
|
|
InitializingCallbacks = new Action[]
|
|
{
|
|
//rebuild the xml cache file if the server is not synced
|
|
() => global::umbraco.content.Instance.RefreshContentFromDatabase(),
|
|
//rebuild indexes if the server is not synced
|
|
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
|
|
// indexes then they can adjust this logic themselves.
|
|
rebuildIndexes
|
|
}
|
|
}));
|
|
}
|
|
|
|
SurfaceControllerResolver.Current = new SurfaceControllerResolver(
|
|
ServiceProvider, ProfilingLogger.Logger,
|
|
PluginManager.ResolveSurfaceControllers());
|
|
|
|
UmbracoApiControllerResolver.Current = new UmbracoApiControllerResolver(
|
|
ServiceProvider, ProfilingLogger.Logger,
|
|
PluginManager.ResolveUmbracoApiControllers());
|
|
|
|
// both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be
|
|
// discovered when CoreBootManager configures the converters. We HAVE to remove one of them
|
|
// here because there cannot be two converters for one property editor - and we want the full
|
|
// RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter.
|
|
// (the limited one, defined in Core, is there for tests)
|
|
PropertyValueConvertersResolver.Current.RemoveType<TinyMceValueConverter>();
|
|
// same for other converters
|
|
PropertyValueConvertersResolver.Current.RemoveType<Core.PropertyEditors.ValueConverters.TextStringValueConverter>();
|
|
PropertyValueConvertersResolver.Current.RemoveType<Core.PropertyEditors.ValueConverters.MarkdownEditorValueConverter>();
|
|
|
|
PublishedCachesResolver.Current = new PublishedCachesResolver(Container, typeof(PublishedCaches));
|
|
|
|
FilteredControllerFactoriesResolver.Current = new FilteredControllerFactoriesResolver(
|
|
ServiceProvider, ProfilingLogger.Logger,
|
|
// add all known factories, devs can then modify this list on application
|
|
// startup either by binding to events or in their own global.asax
|
|
new[]
|
|
{
|
|
typeof (RenderControllerFactory)
|
|
});
|
|
|
|
UrlProviderResolver.Current = new UrlProviderResolver(
|
|
Container, ProfilingLogger.Logger,
|
|
//typeof(AliasUrlProvider), // not enabled by default
|
|
typeof(DefaultUrlProvider),
|
|
typeof(CustomRouteUrlProvider)
|
|
);
|
|
|
|
ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver(Container, typeof(ContentFinderByLegacy404));
|
|
|
|
ContentFinderResolver.Current = new ContentFinderResolver(
|
|
Container, ProfilingLogger.Logger,
|
|
// all built-in finders in the correct order, devs can then modify this list
|
|
// on application startup via an application event handler.
|
|
typeof(ContentFinderByPageIdQuery),
|
|
typeof(ContentFinderByNiceUrl),
|
|
typeof(ContentFinderByIdPath),
|
|
typeof(ContentFinderByNiceUrlAndTemplate),
|
|
typeof(ContentFinderByProfile),
|
|
typeof(ContentFinderByUrlAlias)
|
|
|
|
);
|
|
|
|
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(Container, typeof(SiteDomainHelper));
|
|
|
|
// ain't that a bit dirty? YES
|
|
PublishedCache.XmlPublishedCache.PublishedContentCache.UnitTesting = _isForTesting;
|
|
|
|
ThumbnailProvidersResolver.Current = new ThumbnailProvidersResolver(
|
|
Container, ProfilingLogger.Logger,
|
|
PluginManager.ResolveThumbnailProviders());
|
|
|
|
ImageUrlProviderResolver.Current = new ImageUrlProviderResolver(
|
|
ServiceProvider, ProfilingLogger.Logger,
|
|
PluginManager.ResolveImageUrlProviders());
|
|
|
|
CultureDictionaryFactoryResolver.Current = new CultureDictionaryFactoryResolver(Container, typeof(DefaultCultureDictionaryFactory));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets up MVC/WebApi services
|
|
/// </summary>
|
|
private void SetupMvcAndWebApi()
|
|
{
|
|
//don't output the MVC version header (security)
|
|
MvcHandler.DisableMvcResponseHeader = true;
|
|
|
|
//set master controller factory
|
|
ControllerBuilder.Current.SetControllerFactory(
|
|
new MasterControllerFactory(FilteredControllerFactoriesResolver.Current));
|
|
|
|
//set the render view engine
|
|
ViewEngines.Engines.Add(new RenderViewEngine());
|
|
//set the plugin view engine
|
|
ViewEngines.Engines.Add(new PluginViewEngine());
|
|
|
|
//set model binder
|
|
ModelBinders.Binders.Add(new KeyValuePair<Type, IModelBinder>(typeof(RenderModel), new RenderModelBinder()));
|
|
|
|
////add the profiling action filter
|
|
//GlobalFilters.Filters.Add(new ProfilingActionFilter());
|
|
|
|
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
|
|
new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
|
|
}
|
|
private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
|
|
{
|
|
//store the indexer that needs rebuilding because it's empty for when the boot process
|
|
// is complete and cancel this current event so the rebuild process doesn't start right now.
|
|
args.Cancel = true;
|
|
_indexesToRebuild.Add(args.Indexer);
|
|
}
|
|
}
|
|
}
|