Search code examples
razorforeachumbraco7asp.net-mvc-5

Error on looping through a RelatedLinks property of dynamic Node in Razor


I have a Razor partial which displays my site navigation:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    var home = CurrentPage.Site();
    umbraco.NodeFactory.Node navigationSettingsNode = MySite.Umbraco.NavigationSettings;
    dynamic navigationSettings = new umbraco.MacroEngines.DynamicNode(navigationSettingsNode.Id);
    var settings = home.Children.Where("DocumentTypeAlias == \"Settings\"").First();
}


@if (navigationSettings.HasValue("topNavigation"))
{
    <ul>
        dynamic topNavigation = navigationSettings.topNavigation;
        var topNavigation2 = settings.topNavigation;
        <span>@topNavigation</span>
        <span>@topNavigation2</span>

        foreach(dynamic item in topNavigation)
        {
        <li>
            <a href="@item.link" title="@item.title">@item.caption</a>
        </li>
        }
    </ul>

}

Initially I was looping through topNavigation2 items which worked fine and with no problem.

Now I'm looping through topNavigation items and it throws an error:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'char' does not contain a definition for 'link'

I don't want to use var settings anymore, I want to use only dynamic navigationSettings variable. In order to get the right node of navigationSettings I need to some operation and I don't fancy to paste the same code in every view I want to use it so I want it to be accessible from dll and available to use anywhere.

Also the navigationSettings node in my Umbraco is outside of main content tree so is not a child of Home.

Why isn't it working? Both

        dynamic topNavigation = navigationSettings.topNavigation;
        var topNavigation2 = settings.topNavigation;

produce the same json result and both are dynamic objects.

How to make it work correctly?

I'm using MVC 5.2.3


Solution

  • It looks like your topNavigation property is a string, and so when you call for each on it, it's iterating through the characters in the string.

    Also, don't use NodeFactory, it's deprecated. You should be using IPublishedContent instead.

    I'd use the strongly typed content objects instead of dynamic, as a) they're faster, and b) they're easier to work with.

    Here's a great article explaining the different ways of getting content: https://24days.in/umbraco-cms/2015/strongly-typed-vs-dynamic-content-access/