Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jamie Attwood 207 posts 501 karma points c-trib
    Sep 06, 2022 @ 23:50
    Jamie Attwood
    0

    Umbraco 10 Custom Routes (Trying to cut through the clutter)

    The docs for custom routes has my head spinning. I am upgrading a V8 site to V10 and trying to add simple parameters to the request for use in a custom controller (route hijacking style). Give this a read and tell me that I am crazy: https://our.umbraco.com/documentation/reference/routing/custom-routes/

    In Umbraco 8 I had my code in this component:

    public class RegisterCustomRoutesComponent : IComponent
    {
        public void Initialize()
        {
            // Custom route to RegistrationPage contoller which will use a node with a specific ID as the
            // IPublishedContent for the current rendering page
            RouteTable.Routes.MapUmbracoRoute("RegistrationRoute", "account/register/{aid}/{rid}", new
            {
                controller = "RegistrationPage", //omitted "controller" suffix
                action ="Index", //Controller action
                aid = UrlParameter.Optional, 
                rid = UrlParameter.Optional, 
            }, new UmbracoVirtualNodeByUdiRouteHandler(new GuidUdi(Constants.UdiEntityType.Document, new Guid("1af61142-46e4-4b18-825b-5f2a7c358433"))));
    
        }
    
        public void Terminate()
        {
        }
    
    }
    

    This worked great.

    In U9 and 10 no more components. The close as I can get currently is extending the UmbracoApplicationBuilderExtensions with a class that returns IUmbracoEndpointBuilderContext UseCustomRoutes to handle custom routes that is called from startup.cs:

     app.UseUmbraco()
                .WithMiddleware(u =>
                {
                    u.UseBackOffice();
                    u.UseWebsite();
                })
                .WithEndpoints(u =>
                {
                    u.UseInstallerEndpoints();
                    u.UseBackOfficeEndpoints();
                    u.UseWebsiteEndpoints();
                    u.UseCustomRoutes();//JA custom UmbracoApplicationBuilderExtension
                });
    

    Here is the extension class:

    using Microsoft.AspNetCore.Builder;
    using System.Web.Mvc;
    using Umbraco.Cms.Core.Models.PublishedContent;
    using Umbraco.Cms.Web.Common.ApplicationBuilder;
    using Umbraco.Extensions;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Umbraco.Cms.Core.Web;
    using ActionExecutingContext = Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace Protean.Core.Configuration
    {
        public static class UmbracoApplicationBuilderExtensions
        {
            public static IUmbracoEndpointBuilderContext UseCustomRoutes(this IUmbracoEndpointBuilderContext app)
            {
                if (!app.RuntimeState.UmbracoCanBoot())
                {
                    return app;
                }
    
                app.EndpointRouteBuilder.MapControllerRoute(
                "Registration Page Controller",
                "/account/register/{aid}/{rid}",
                new
                {
                    Controller = "RegistrationPage",
                    Action = "Index",
                    aid = UrlParameter.Optional, 
                    rid = UrlParameter.Optional, 
                }).ForUmbracoPage(FindRegistrationPage);
    
                return app;
    
    
    
            }
            private static IPublishedContent FindRegistrationPage(ActionExecutingContext actionExecutingContext)
            {
                var umbracoContextAccessor = actionExecutingContext.HttpContext.RequestServices.GetRequiredService<IUmbracoContextAccessor>();
                var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
                return umbracoContext.Content.GetById(new Guid("1af61142-46e4-4b18-825b-5f2a7c358433"));
            }
        }
    }
    

    Debugging is not telling me anything. It appears that the route is added to the route table, however the controller is never invoked. FYI This is not a vanilla route, just want to add to parameters to the request parameters for a known umbraco page (route hijacking) that can be then digested by the controller...

    Any thoughts or suggestions would be really great...thanks in advance!

    Jamie

  • Jamie Attwood 207 posts 501 karma points c-trib
    Sep 07, 2022 @ 14:46
    Jamie Attwood
    105

    Finally solved this. Here is my experience - hopefully it will help someone struggling with the same issues.

    There are no issues with the above code - this works on the routing side of things.

    After 4 hours and good night's sleep I sat down and re-read the docs yet again. This time I noticed the subtle difference that the controller in question must inherit from UmbracoPageController and NOT RenderController that you might normally use. I guess this somehow flags this controller as being different and has custom routing - without this you will see that you will get multiple registrations of the same controller at runtime...

    If you are doing a lot of route hijacking like I am this is very easy to overlook and the difference between having a full head of hair and... not.

    With this change, we are up and running with route hijacking (of sorts) with custom route parameters.

Please Sign in or register to post replies

Write your reply to:

Draft