using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; using System.IO; using System.Linq; using System.Web.Configuration; using System.Web.Http; using System.Web.Http.Dispatcher; using System.Web.Mvc; using ClientDependency.Core.CompositeFiles.Providers; using ClientDependency.Core.Config; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Web.JavaScript; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Web.Runtime { public sealed class WebInitialComponent : IComponent { private readonly IGlobalSettings _globalSettings; public WebInitialComponent(IGlobalSettings globalSettings) { _globalSettings = globalSettings; } public void Initialize() { // setup mvc and webapi services SetupMvcAndWebApi(); // When using a non-web runtime and this component is loaded ClientDependency explodes because it'll // want to access HttpContext.Current, which doesn't exist if (IOHelper.IsHosted) { ConfigureClientDependency(_globalSettings); } // Disable the X-AspNetMvc-Version HTTP Header MvcHandler.DisableMvcResponseHeader = true; // wrap view engines in the profiling engine WrapViewEngines(ViewEngines.Engines); // add global filters ConfigureGlobalFilters(); } public void Terminate() { } private static void ConfigureGlobalFilters() { GlobalFilters.Filters.Add(new EnsurePartialViewMacroViewContextFilterAttribute()); } // internal for tests internal static void WrapViewEngines(IList viewEngines) { if (viewEngines == null || viewEngines.Count == 0) return; var originalEngines = viewEngines.ToList(); viewEngines.Clear(); foreach (var engine in originalEngines) { var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine(engine); viewEngines.Add(wrappedEngine); } } private static void SetupMvcAndWebApi() { //don't output the MVC version header (security) MvcHandler.DisableMvcResponseHeader = true; // set master controller factory var controllerFactory = new MasterControllerFactory(() => Current.FilteredControllerFactories); ControllerBuilder.Current.SetControllerFactory(controllerFactory); // set the render & plugin view engines ViewEngines.Engines.Add(new RenderViewEngine()); ViewEngines.Engines.Add(new PluginViewEngine()); //set model binder ModelBinderProviders.BinderProviders.Add(ContentModelBinder.Instance); // is a provider ////add the profiling action filter //GlobalFilters.Filters.Add(new ProfilingActionFilter()); GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration)); } private static void ConfigureClientDependency(IGlobalSettings globalSettings) { // Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK] XmlFileMapper.FileMapDefaultFolder = SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; BaseCompositeFileProcessingProvider.UrlTypeDefault = CompositeUrlType.Base64QueryStrings; // Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file // location to be there if (globalSettings.LocalTempStorageLocation == LocalTempStorage.EnvironmentTemp) { var cachePath = globalSettings.LocalTempPath; //set the file map and composite file default location to the %temp% location BaseCompositeFileProcessingProvider.CompositeFilePathDefaultFolder = XmlFileMapper.FileMapDefaultFolder = Path.Combine(cachePath, "ClientDependency"); } if (ConfigurationManager.GetSection("system.web/httpRuntime") is HttpRuntimeSection section) { //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); } } }