// internal for tests internal static void CreateRoutes( IUmbracoContextAccessor umbracoContextAccessor, IGlobalSettings globalSettings, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes) { var umbracoPath = globalSettings.GetUmbracoMvcArea(); // 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(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory()); // register install routes RouteTable.Routes.RegisterArea <UmbracoInstallArea>(); // register all back office routes RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings)); // plugin controllers must come first because the next route will catch many things RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes); }
public WebFinalComponent(IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IGlobalSettings globalSettings) { _umbracoContextAccessor = umbracoContextAccessor; _surfaceControllerTypes = surfaceControllerTypes; _apiControllerTypes = apiControllerTypes; _globalSettings = globalSettings; }
/// <summary> /// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin /// </summary> public static MvcForm BeginUmbracoForm( this IHtmlHelper html, string action, Type surfaceType, object?additionalRouteVals, IDictionary <string, object?> htmlAttributes, FormMethod method) { if (action == null) { throw new ArgumentNullException(nameof(action)); } if (string.IsNullOrWhiteSpace(action)) { throw new ArgumentException( "Value can't be empty or consist only of white-space characters.", nameof(action)); } if (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } SurfaceControllerTypeCollection surfaceControllerTypeCollection = GetRequiredService <SurfaceControllerTypeCollection>(html); Type?surfaceController = surfaceControllerTypeCollection.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } PluginControllerMetadata metaData = PluginController.GetMetadata(surfaceController); var area = string.Empty; if (metaData.AreaName.IsNullOrWhiteSpace() == false) { // Set the area to the plugin area area = metaData.AreaName; } return(html.BeginUmbracoForm( action, metaData.ControllerName, area !, additionalRouteVals, htmlAttributes, method)); }
/// <summary> /// Initializes a new instance of the <see cref="FrontEndRoutes" /> class. /// </summary> public FrontEndRoutes( IOptions <GlobalSettings> globalSettings, IHostingEnvironment hostingEnvironment, IRuntimeState runtimeState, SurfaceControllerTypeCollection surfaceControllerTypeCollection, UmbracoApiControllerTypeCollection apiControllers) { _runtimeState = runtimeState; _surfaceControllerTypeCollection = surfaceControllerTypeCollection; _apiControllers = apiControllers; _umbracoPathSegment = globalSettings.Value.GetUmbracoMvcArea(hostingEnvironment); }
/// <summary> /// Returns the result of a child action of a SurfaceController /// </summary> public static IHtmlContent ActionLink(this IHtmlHelper htmlHelper, string actionName, Type surfaceType) { if (actionName == null) { throw new ArgumentNullException(nameof(actionName)); } if (string.IsNullOrWhiteSpace(actionName)) { throw new ArgumentException( "Value can't be empty or consist only of white-space characters.", nameof(actionName)); } if (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } SurfaceControllerTypeCollection surfaceControllerTypeCollection = GetRequiredService <SurfaceControllerTypeCollection>(htmlHelper); Type?surfaceController = surfaceControllerTypeCollection.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var routeVals = new RouteValueDictionary(new { area = string.Empty }); PluginControllerMetadata metaData = PluginController.GetMetadata(surfaceController); if (!metaData.AreaName.IsNullOrWhiteSpace()) { // set the area to the plugin area if (routeVals.ContainsKey("area")) { routeVals["area"] = metaData.AreaName; } else { routeVals.Add("area", metaData.AreaName); } } return(htmlHelper.ActionLink(actionName, metaData.ControllerName, routeVals)); }
protected override void Compose() { base.Compose(); // set the default RenderMvcController Current.DefaultRenderMvcControllerType = typeof(RenderMvcController); // FIXME: Wrong! var surfaceControllerTypes = new SurfaceControllerTypeCollection(Composition.TypeLoader.GetSurfaceControllers()); Composition.RegisterUnique(surfaceControllerTypes); var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(Composition.TypeLoader.GetUmbracoApiControllers()); Composition.RegisterUnique(umbracoApiControllerTypes); Composition.RegisterUnique <IShortStringHelper>(_ => new DefaultShortStringHelper(SettingsForTests.GetDefaultUmbracoSettings())); }
public WebRuntimeComponent( IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IPublishedSnapshotService publishedSnapshotService, IUserService userService, IUmbracoSettingsSection umbracoSettings, IGlobalSettings globalSettings, IVariationContextAccessor variationContextAccessor, UrlProviderCollection urlProviders) { _umbracoContextAccessor = umbracoContextAccessor; _surfaceControllerTypes = surfaceControllerTypes; _apiControllerTypes = apiControllerTypes; _publishedSnapshotService = publishedSnapshotService; _userService = userService; _umbracoSettings = umbracoSettings; _globalSettings = globalSettings; _variationContextAccessor = variationContextAccessor; _urlProviders = urlProviders; }
private static void RoutePluginControllers( IGlobalSettings globalSettings, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes) { var umbracoPath = globalSettings.GetUmbracoMvcArea(); // need to find the plugin controllers and route them var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).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); } } // get the plugin controllers that are unique to each area (group by) var pluginSurfaceControlleres = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace() == false); var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName); // loop through each area defined amongst the controllers foreach (var g in groupedAreas) { // create & register an area for the controllers (this will throw an exception if all controllers are not in the same area) var pluginControllerArea = new PluginControllerArea(globalSettings, g.Select(PluginController.GetMetadata)); RouteTable.Routes.RegisterArea(pluginControllerArea); } }
public override void Compose(Composition composition) { base.Compose(composition); composition.Register <UmbracoInjectedModule>(); composition.RegisterUnique <IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors composition.ComposeWebMappingProfiles(); //register the install components //NOTE: i tried to not have these registered if we weren't installing or upgrading but post install when the site restarts //it still needs to use the install controller so we can't do that composition.ComposeInstaller(); // register membership stuff composition.Register(factory => Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider()); composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance <IMemberService>())); composition.Register <MembershipHelper>(); // register accessors for cultures composition.RegisterUnique <IDefaultCultureAccessor, DefaultCultureAccessor>(); composition.RegisterUnique <IVariationContextAccessor, HttpContextVariationContextAccessor>(); // register the http context and umbraco context accessors // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when // we have no http context, eg when booting Umbraco or in background threads, so instead // let's use an hybrid accessor that can fall back to a ThreadStatic context. composition.RegisterUnique <IUmbracoContextAccessor, HybridUmbracoContextAccessor>(); // register a per-request HttpContextBase object // is per-request so only one wrapper is created per request composition.Register <HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance <IHttpContextAccessor>().HttpContext), Lifetime.Request); // register the published snapshot accessor - the "current" published snapshot is in the umbraco context composition.RegisterUnique <IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>(); // we should stop injecting UmbracoContext and always inject IUmbracoContextAccessor, however at the moment // there are tons of places (controllers...) which require UmbracoContext in their ctor - so let's register // a way to inject the UmbracoContext - and register it per-request to be more efficient //TODO: stop doing this composition.Register(factory => factory.GetInstance <IUmbracoContextAccessor>().UmbracoContext, Lifetime.Request); // register the umbraco helper composition.RegisterUnique <UmbracoHelper>(); // register distributed cache composition.RegisterUnique(f => new DistributedCache()); // replace some services composition.RegisterUnique <IEventMessagesFactory, DefaultEventMessagesFactory>(); composition.RegisterUnique <IEventMessagesAccessor, HybridEventMessagesAccessor>(); composition.RegisterUnique <IApplicationTreeService, ApplicationTreeService>(); composition.RegisterUnique <ISectionService, SectionService>(); composition.RegisterUnique <IExamineManager>(factory => ExamineManager.Instance); // configure the container for web composition.ConfigureForWeb(); composition.RegisterUnique <Dashboards>(); composition .ComposeUmbracoControllers(GetType().Assembly) .SetDefaultRenderMvcController <RenderMvcController>(); // default controller for template views composition.WithCollectionBuilder <SearchableTreeCollectionBuilder>() .Add(() => composition.TypeLoader.GetTypes <ISearchableTree>()); // fixme which searchable trees?! composition.Register <UmbracoTreeSearcher>(Lifetime.Request); composition.WithCollectionBuilder <EditorValidatorCollectionBuilder>() .Add(() => composition.TypeLoader.GetTypes <IEditorValidator>()); composition.WithCollectionBuilder <TourFilterCollectionBuilder>(); composition.RegisterUnique <UmbracoFeatures>(); composition.WithCollectionBuilder <ActionCollectionBuilder>() .Add(() => composition.TypeLoader.GetTypes <IAction>()); var surfaceControllerTypes = new SurfaceControllerTypeCollection(composition.TypeLoader.GetSurfaceControllers()); composition.RegisterUnique(surfaceControllerTypes); var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(composition.TypeLoader.GetUmbracoApiControllers()); composition.RegisterUnique(umbracoApiControllerTypes); // 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) - same for others composition.WithCollectionBuilder <PropertyValueConverterCollectionBuilder>() .Remove <TinyMceValueConverter>() .Remove <TextStringValueConverter>() .Remove <MarkdownEditorValueConverter>(); // add all known factories, devs can then modify this list on application // startup either by binding to events or in their own global.asax composition.WithCollectionBuilder <FilteredControllerFactoryCollectionBuilder>() .Append <RenderControllerFactory>(); composition.WithCollectionBuilder <UrlProviderCollectionBuilder>() .Append <AliasUrlProvider>() .Append <DefaultUrlProvider>() .Append <CustomRouteUrlProvider>(); composition.RegisterUnique <IContentLastChanceFinder, ContentFinderByLegacy404>(); composition.WithCollectionBuilder <ContentFinderCollectionBuilder>() // all built-in finders in the correct order, // devs can then modify this list on application startup .Append <ContentFinderByPageIdQuery>() .Append <ContentFinderByUrl>() .Append <ContentFinderByIdPath>() //.Append<ContentFinderByUrlAndTemplate>() // disabled, this is an odd finder .Append <ContentFinderByUrlAlias>() .Append <ContentFinderByRedirectUrl>(); composition.RegisterUnique <ISiteDomainHelper, SiteDomainHelper>(); composition.RegisterUnique <ICultureDictionaryFactory, DefaultCultureDictionaryFactory>(); // register *all* checks, except those marked [HideFromTypeFinder] of course composition.WithCollectionBuilder <HealthCheckCollectionBuilder>() .Add(() => composition.TypeLoader.GetTypes <HealthCheck.HealthCheck>()); composition.WithCollectionBuilder <HealthCheckNotificationMethodCollectionBuilder>() .Add(() => composition.TypeLoader.GetTypes <HealthCheck.NotificationMethods.IHealthCheckNotificationMethod>()); // auto-register views composition.RegisterAuto(typeof(UmbracoViewPage <>)); // register published router composition.RegisterUnique <PublishedRouter>(); composition.Register(_ => Current.Configs.Settings().WebRouting); // register preview SignalR hub composition.RegisterUnique(_ => GlobalHost.ConnectionManager.GetHubContext <PreviewHub>()); // register properties fallback composition.RegisterUnique <IPublishedValueFallback, PublishedValueFallback>(); // register known content apps composition.WithCollectionBuilder <ContentAppFactoryCollectionBuilder>() .Append <ListViewContentAppFactory>() .Append <ContentEditorContentAppFactory>() .Append <ContentInfoContentAppFactory>(); }