Copied to clipboard

Flag this post as spam?

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


  • David Armitage 510 posts 2081 karma points
    Aug 20, 2017 @ 04:47
    David Armitage
    0

    UmbracoVirtualNodeByIdRouteHandler - How to get the node by Guid (Custom Routing)

    Hi Guys,

    Here is a bit of an issue I can trying to figure out.

    1. I started using Umbraco Courier 3 and it works great.

    2. I noticed when Courier uploads nodes/documents to the live environment the Id is different but it retains the same Guid. Fine! I expected this would be the case.

    3. Because of this I have started referencing nodes by Guid rather than the Id since there wont be any confusion on local, staging, and live when referencing nodes.

    4. This has been working fine for everything except this one issue.


    Part of my application has custom routes within the application starting event.

    E.g

    RouteTable.Routes.MapUmbracoRoute(
                    "JobSearch1",
                    "find-a-job/search-jobs/{value1}",
                    new
                    {
                        controller = "Routing",
                        action = "JobList"
                    },
                    new UmbracoVirtualNodeByIdRouteHandler(1276));//job list page Id
    

    Obviously as per my description above I no longer want to use Ids as the primary referencing. So this line of code becomes an issue.

    new UmbracoVirtualNodeByIdRouteHandler(1276))
    

    I couldn't find an equivilant that accepts a Guid. First of all if anyone knows an equivilant then please shout out.

    I attempted to get around this by the following code

    var umbracoHelper = new Umbraco.Web.UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
    int Id = umbracoHelper.TypedContent(guid).Id;
    
     RouteTable.Routes.MapUmbracoRoute(
                        "JobSearch1",
                        "find-a-job/search-jobs/{value1}",
                        new
                        {
                            controller = "Routing",
                            action = "JobList"
                        },
                        new UmbracoVirtualNodeByIdRouteHandler(Id));//job list page Id
    

    The issue here is that in the starting event the context doesn't exist. I have using the EnforceUmbracoContext in the past with similar issues but in this case its not working and I am really not confidant this is the way to go. Its too much of an hack and I am guessing it's going to cause all sorts of problems at a later date.

    https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/57892-IPublishedContent-and-GatheringNodeData

    Cant anyone point me in the right direction or give me some advise on this?

    Thanks in advance.

    Kind Regards

    David

  • David Armitage 510 posts 2081 karma points
    Aug 20, 2017 @ 05:36
    David Armitage
    100

    Hi,

    So I have figured out a way around this. I am not sure if this the best way so I am keen to hear what other people are doing.

    I use the same code for the custom route. The only difference is instead of using the Id of the page this will route to for the virtual node I simply use the Id of the homepage. This will always be the same between staging and live. Plus its not that important as long as its an Id that exists.

      RouteTable.Routes.MapUmbracoRoute(
                        "JobSearch1",
                        "find-a-job/search-jobs/{value1}",
                        new
                        {
                            controller = "Routing",
                            action = "JobList"
                        },
                        new UmbracoVirtualNodeByIdRouteHandler(1063));//Homepage Node Id
    

    The next part of this hack is within the controller handing the return of the model. I simply created a new RenderModel based on the Guid I wanted to use then passed this back out instead of the virtual node as I was previously using.

    public class RoutingController : Umbraco.Web.Mvc.RenderMvcController
    {
        public ActionResult JobList(RenderModel model)
        {
            model = new RenderModel(BusinessManager.GetPublishedContentByGuid(Guid.Parse("a25dbd15-f4fb-4fc5-9b4d-23c40fd2e115")));
            return View("JobList", model);
        }
    }
    

    I hope this helps someone. If anyone knows of a better solution please let me know.

    Kind Regards

    David

  • Damiaan 442 posts 1302 karma points MVP 6x c-trib
    Aug 20, 2017 @ 20:14
    Damiaan
    2

    Hi David,

    You should never reference to a hardcoded node. Rather create your own virtual route handler.

    public class FindJobPageRouteHandler : UmbracoVirtualNodeRouteHandler
    {
        protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
        {
            // change this to whatever you need, but make sure it is fast!
            var jobspage = umbracoContext.ContentCache.GetAtRoot().First().FirstChild<MyJobAreaDocType>(); 
            return jobspage ;
        }
    }
    

    Then replace your new UmbracoVirtualNodeByIdRouteHandler(1063) with new FindJobPageRouteHandler() when adding your route.

    Like this you won't need the context to route to the correct page.

    Hope this helps

    Kind regards
    Damiaan

    PS: I won't mark your own reply as an accepted solution, if you want other people to jump in. Btw, it is only a workaround, not a solution. :-p

  • David Armitage 510 posts 2081 karma points
    Aug 21, 2017 @ 01:31
    David Armitage
    0

    I can confirm I was also able to implement this solution as described. Thanks for you help. Much appreciated :)

  • JacobMarcussen 6 posts 76 karma points
    1 day ago
    JacobMarcussen
    0

    I have the same setup running on Umbraco 7. But i've started to migrate to Umbraco 13. How would that setup then work. It doesnt seem like there's a way to pass the node id from the MapControllerRoute in my program.cs?

    Any insight would be appreciated :)

Please Sign in or register to post replies

Write your reply to:

Draft