// 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));
    }
Пример #4
0
 /// <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);
            }
        }
Пример #9
0
        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>();
        }