Copied to clipboard

Flag this post as spam?

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


  • Alex Gill 26 posts 61 karma points
    Sep 09, 2013 @ 18:26
    Alex Gill
    0

    "umbraco-route-def" missing from RouteData.DataTokens

    When using @Html.Action("method", "controller") to retrieve data from some SurfaceControllers the CurrentPage property throws an exception:

    Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request

    This exception is thrown because the route definition is not present in the data token lookup for the key "umbraco-route-def" (SurfaceController.TryGetRouteDefinitionFromAncestorViewContexts)

    This only occurs for some Document Types and not others.

    • Umbraco version: 6.1.5
    • ASP.NET version: 4.0.30319
    • Windows 7, IIS 7.5

    The exception occurs in get_CurrentPage() on SurfaceController, which is called by some subclass code.

    Any help or advice appreciated!

  • Alex Gill 26 posts 61 karma points
    Sep 10, 2013 @ 11:54
    Alex Gill
    2

    I fixed my issue - it is caused by this bug in Umbraco.Web.Mvc.RenderRouteHandler:

        internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest publishedContentRequest)
        {
            var defaultControllerType = DefaultRenderMvcControllerResolver.Current.GetDefaultControllerType();
            var defaultControllerName = ControllerExtensions.GetControllerName(defaultControllerType);
            //creates the default route definition which maps to the 'UmbracoController' controller
            var def = new RouteDefinition
                {
                    ControllerName = defaultControllerName,
                    ControllerType = defaultControllerType,
                    PublishedContentRequest = publishedContentRequest,
                    ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(),
                    HasHijackedRoute = false
                };
    
            //check that a template is defined), if it doesn't and there is a hijacked route it will just route
            // to the index Action
            if (publishedContentRequest.HasTemplate)
            {
                //the template Alias should always be already saved with a safe name.
                //if there are hyphens in the name and there is a hijacked route, then the Action will need to be attributed
                // with the action name attribute.
                var templateName = publishedContentRequest.TemplateAlias.Split('.')[0].ToSafeAlias();
                def.ActionName = templateName;
            }
    
            //check if there's a custom controller assigned, base on the document type alias.
            var controllerType = _controllerFactory.GetControllerTypeInternal(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias);
    
            //check if that controller exists
            if (controllerType != null)
            {
                //ensure the controller is of type 'IRenderMvcController' and ControllerBase
                if (TypeHelper.IsTypeAssignableFrom<IRenderMvcController>(controllerType)
                    && TypeHelper.IsTypeAssignableFrom<ControllerBase>(controllerType))
                {
                    //set the controller and name to the custom one
                    def.ControllerType = controllerType;
                    def.ControllerName = ControllerExtensions.GetControllerName(controllerType);
                    if (def.ControllerName != defaultControllerName)
                    {
                        def.HasHijackedRoute = true;
                    }
                }
                else
                {
                    LogHelper.Warn<RenderRouteHandler>(
                        "The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must implement '{2}' and inherit from '{3}'.",
                        () => publishedContentRequest.PublishedContent.DocumentTypeAlias,
                        () => controllerType.FullName,
                        () => typeof(IRenderMvcController).FullName,
                        () => typeof(ControllerBase).FullName);
                    //exit as we cannnot route to the custom controller, just route to the standard one.
                    return def;
                }
            }
    
            //store the route definition
            requestContext.RouteData.DataTokens["umbraco-route-def"] = def;
    
            return def;
        }
    

    The route handler does a check to see if there is a controller with a matching name to the document type - it has some special handling for this case that I was not aware of. If you have a Document Type with an Alias that is the same as one of your controllers (e.g. Registration + RegistrationController) this error occurs because of the early-exit in the else block that skips the line adding the RouteDefinition to the data token dictionary.

  • Moran 285 posts 934 karma points
    Dec 14, 2013 @ 08:01
    Moran
    0

    Thanks That saved me a lot of messing around :)

  • Haris 15 posts 35 karma points
    Sep 16, 2014 @ 13:24
    Haris
    0

    hey everybody

    I'm having the same problem with the RedirectToCurrentUmbracoPage() and I came across this post but not really sure what to do with it.. . . Alex can you please elaborate more on this subject?

    Where should I put the code you wrote in the earlier post?

    Greetings

Please Sign in or register to post replies

Write your reply to:

Draft