Error executing template "Designs/Swift/Navigation/COMM_EventTabs.cshtml"
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at CompiledRazorTemplates.Dynamic.RazorEngine_394e850960994fb69b77c3edfa28ca61.Execute() in C:\inetpub\wwwroot\directions2023\Files\Templates\Designs\Swift\Navigation\COMM_EventTabs.cshtml:line 7
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.Navigation.NavigationTreeViewModel> @using Dynamicweb @using System.Text.RegularExpressions @using Dynamicweb.Frontend @{ string theme = !string.IsNullOrEmpty(Model.Parameters["theme"].ToString()) ? Model.Parameters["theme"].ToString() : string.Empty; string navOrientation = !string.IsNullOrEmpty(Model.Parameters["navOrientation"].ToString()) ? Model.Parameters["navOrientation"].ToString() : string.Empty; string navAlignment = !string.IsNullOrEmpty(Model.Parameters["navAlignment"].ToString()) ? Model.Parameters["navAlignment"].ToString() : string.Empty; string linkFontWeight = !string.IsNullOrEmpty(Model.Parameters["LinkFontWeight"].ToString()) ? Model.Parameters["LinkFontWeight"].ToString() : string.Empty; string linkCasing = !string.IsNullOrEmpty(Model.Parameters["LinkCasing"].ToString()) ? Model.Parameters["LinkCasing"].ToString() : string.Empty; string linkFontSize = !string.IsNullOrEmpty(Model.Parameters["LinkFontSize"].ToString()) ? Model.Parameters["LinkFontSize"].ToString() : string.Empty; string layout = !string.IsNullOrEmpty(Model.Parameters["Layout"].ToString()) ? Model.Parameters["Layout"].ToString() : string.Empty; string iconSize = "icon-3"; if (linkFontSize == "fs-7") { iconSize = "icon-2"; } if (linkFontSize == "fs-5") { iconSize = "icon-4"; } } <div class="grid"> <div class="g-col-12"> <nav class="navbar navbar-expand-lg d-flex py-0 overflow-y-auto @navOrientation @navAlignment"> @{@RenderFirstLevelNodes(Model.Nodes, theme, navOrientation, linkFontWeight, linkCasing, linkFontSize, iconSize, layout)} </nav> </div> </div> @helper RenderFirstLevelNodes(IEnumerable<Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel> nodes, string theme, string navOrientation, string linkFontWeight, string linkCasing, string linkFontSize, string iconSize, string layout) { int imageHeight = 50; string logo = Model.Parameters.ContainsKey("Logo") ? Model.Parameters["Logo"].ToString() : string.Empty; int logoHeight = Model.Parameters.ContainsKey("LogoHeight") ? Convert.ToInt32(Model.Parameters["LogoHeight"]) : 50; string rootPageId = Model.Parameters.ContainsKey("RootPageId") ? Model.Parameters["RootPageId"].ToString() : string.Empty; var rootPageFriendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?ID=" + rootPageId); string theme = Model.Parameters.ContainsKey("theme") ? Model.Parameters["theme"].ToString() : string.Empty; string themeSticky = Model.Parameters.ContainsKey("themeSticky") ? Model.Parameters["themeSticky"].ToString() : string.Empty; bool showOnlyFirstNavLevel = Model.Parameters.ContainsKey("ShowOnlyFirstNavLevel") ? Convert.ToBoolean(Model.Parameters["ShowOnlyFirstNavLevel"].ToString()) : false; int gridRowId = Model.Parameters.ContainsKey("GridRowId") ? Convert.ToInt32(Model.Parameters["GridRowId"].ToString()) : 0; int currentParagraphId = Pageview.CurrentParagraph != null ? Pageview.CurrentParagraph.ID : gridRowId; string menuId = Model.Parameters.ContainsKey("menu-id") ? $"menu_{Model.Parameters["menu-id"].ToString().ToLower()}" : string.Empty; string firstItemActive = !nodes.Any(node => node.InPath || node.IsActive) ? "active" : string.Empty; <ul class="overflow-y-auto align-items-center w-100 gap-lg-3 gap-1 navbar-nav flex-nowrap @(navOrientation == "vertical" ? "flex-column" : navOrientation)"> <li class="nav-item flex-1"> <div class="item-container first @firstItemActive"> <a href="@rootPageFriendlyUrl" class="first-item fw-bold p-2 nav-link text-nowrap text-decoration-underline-hover @linkFontSize @linkFontWeight @linkCasing"> @Translate("Intro") </a> @if (!string.IsNullOrEmpty(logo)) { var parms = new Dictionary<string, object>(); parms.Add("alt", "logo"); parms.Add("height", logoHeight); <a href="@rootPageFriendlyUrl" class="logo d-none"> @RenderPartial("../Components/Image.cshtml", new FileViewModel { Path = logo }, parms) </a> } </div> </li> @foreach (var node in nodes) { var page = Dynamicweb.Content.Services.Pages.GetPage(node.PageId); var pageType = !string.IsNullOrEmpty(page.ItemType) ? page.ItemType : "Swift_Page"; string pageIcon = string.Empty; if (page.PropertyItem is object && page.PropertyItem.TryGetValue("Icon", out object pageIconValue)) { pageIcon = Dynamicweb.Core.Converter.ToString(pageIconValue); } string preferencesLayout = page.Item?["PreferencesLayout"] != null ? page.Item["PreferencesLayout"].ToString() : ""; string preferencesType = "language"; bool countrySelector = page.Item?["CountrySelector"] != null ? Convert.ToBoolean(page.Item["CountrySelector"].ToString()) : false; bool languageSelector = page.Item?["LanguageSelector"] != null ? Convert.ToBoolean(page.Item["LanguageSelector"].ToString()) : false; bool currencySelector = page.Item?["CurrencySelector"] != null ? Convert.ToBoolean(page.Item["CurrencySelector"].ToString()) : false; string dropdownAttributes = string.Empty; string dropdownClasses = string.Empty; var hasChildren = node.Nodes.Count() > 0 || pageType == "Swift_SignIn"; if (hasChildren && !showOnlyFirstNavLevel) { dropdownAttributes = hasChildren ? " role=\"button\" aria-haspopup=\"true\" aria-expanded=\"false\" data-bs-toggle=\"dropdown\" data-bs-offset=\"0,0\"" : ""; } string isActive = node.InPath || node.IsActive ? " active" : ""; string nodeId = !string.IsNullOrEmpty(node.GroupId) ? "Navigation_" + node.GroupId + "_" + currentParagraphId : "Navigation_Page_Desktop_" + node.PageId.ToString() + "_" + currentParagraphId; if (pageType != "Swift_Preferences") { <li class="nav-item@(hasChildren ? " dropdown" : "") flex-1 @(isActive)"> <div class="item-container @(isActive)"> @if (node.IsClickable) { <a href="@node.Link" class="fw-bold p-2 nav-link text-nowrap text-decoration-underline-hover @linkFontSize @linkFontWeight @linkCasing@(isActive)@(hasChildren ? " dropdown-toggle" : "")" @dropdownAttributes @(node.IsActive ? " aria-current='page'" : "") id="@nodeId"> @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout)} </a> } else { <span class="fw-bold p-2 nav-link text-nowrap @linkFontSize @linkFontWeight @linkCasing@(hasChildren ? " dropdown-toggle " : "")" @dropdownAttributes id="@nodeId"> @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout)} </span> } </div> @if (hasChildren) { if (!showOnlyFirstNavLevel) { <ul class="dropdown-menu @(theme)" aria-labelledby="@nodeId"> @foreach (var subnode in node.Nodes) //Standard pages { nodeId = !string.IsNullOrEmpty(subnode.GroupId) ? "Navigation_" + subnode.GroupId + "_" + currentParagraphId : "Navigation_Page_" + subnode.PageId.ToString() + "_" + currentParagraphId; int count = 1; @RenderSubNodes(subnode, 2, nodeId, count) } @if (pageType == "Swift_SignIn") //Sign out link { if (Pageview.User != null) { string link = "/Admin/Public/ExtranetLogoff.aspx?redirect=no"; <li><hr class="dropdown-divider"></li> if (Dynamicweb.Security.UserManagement.User.GetCurrentSecondaryUser() != null) { <li> <a href="Default.aspx?ID=@(Pageview.ID)&DwExtranetRemoveSecondaryUser=1" class="dropdown-item py-2 text-decoration-underline-hover swift_sign-out-as-customer-link @linkFontSize @linkFontWeight @linkCasing" id="SignInButton_@currentParagraphId">@Translate("Sign out as a customer")</a> </li> } <li> <a href="@link" class="dropdown-item py-2 text-decoration-underline-hover swift_sign-out-link @linkFontSize @linkFontWeight @linkCasing">@Translate("Sign out")</a> </li> } } </ul> } } </li> } else { if (preferencesLayout == "modal") { string groupId = Dynamicweb.Context.Current.Request["GroupID"] != null ? Dynamicweb.Context.Current.Request["GroupID"].ToString() : ""; string productId = Dynamicweb.Context.Current.Request["ProductID"] != null ? Dynamicweb.Context.Current.Request["ProductID"].ToString() : ""; string variantId = Dynamicweb.Context.Current.Request["VariantID"] != null ? Dynamicweb.Context.Current.Request["VariantID"].ToString() : ""; <li class="nav-item@(hasChildren ? " dropdown" : "")"> <form action="/Default.aspx?ID=@node.PageId" data-response-target-element="PreferencesModalContent" data-layout-template="Swift_Preferences.cshtml" data-preloader="inline"> <input type="hidden" name="CurrentPageID" value="@Pageview.ID"> <input type="hidden" name="GroupID" value="@groupId"> <input type="hidden" name="ProductID" value="@productId"> <input type="hidden" name="VariantID" value="@variantId"> <button type="button" onmouseover="swift.PageUpdater.Update(event)" onclick="swift.PageUpdater.Update(event)" class="btn nav-link p-2 text-nowrap border-0 swift_open-preferences-modal @linkFontSize @linkFontWeight @linkCasing" data-bs-toggle="modal" data-bs-target="#PreferencesModal" id="OpenPreferences_@currentParagraphId"> @if (languageSelector) { {@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout, "language")} } else { {@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout)} } </button> </form> </li> } else { var ecomCountries = Dynamicweb.Ecommerce.Services.Countries.GetCountries(); var currencies = Dynamicweb.Ecommerce.Services.Currencies.GetAllCurrencies(); if (languageSelector) { List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>(); if (Pageview.Page.Area.IsMaster) { languages.Add(Pageview.Page); if (Pageview.Page.Languages != null) { foreach (var language in Pageview.Page.Languages) { if (language.Area.Active == true) { languages.Add(language); } } } } else { languages.Add(Pageview.Page.MasterPage); if (Pageview.Page.MasterPage != null) { if (Pageview.Page.MasterPage.Languages != null) { foreach (var language in Pageview.Page.MasterPage.Languages) { if (language.Area.Active == true) { languages.Add(language); } } } } } if (languages.Count > 1) { preferencesType = "language"; {@RenderPreferencesDropdown(node, preferencesType, linkFontSize, linkFontWeight, linkCasing, theme, pageType, pageIcon, iconSize, layout)} } } if (countrySelector && ecomCountries.Count > 1) { preferencesType = "country"; {@RenderPreferencesDropdown(node, preferencesType, linkFontSize, linkFontWeight, linkCasing, theme, pageType, pageIcon, iconSize, layout)} } if (currencySelector && currencies.Count() > 1) { preferencesType = "currency"; {@RenderPreferencesDropdown(node, preferencesType, linkFontSize, linkFontWeight, linkCasing, theme, pageType, pageIcon, iconSize, layout)} } } } } </ul> } @helper RenderNavigationItem(Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel node, string pageType, string pageIcon, string iconSize, string layout, string preferencesType = "") { var page = Dynamicweb.Content.Services.Pages.GetPage(node.PageId); if (pageType == "Swift_Cart") //Mini cart { string cartId = ""; if (page.Item["ContextCart"] != null) { cartId = !string.IsNullOrEmpty(page.Item["ContextCart"].ToString()) ? "ID=\"Cart_" + page.Item["ContextCart"].ToString() + "\"" : ""; } string jsCartClass = string.IsNullOrEmpty(cartId) ? "js-cart-qty" : ""; double totalProducts = 0; Dynamicweb.Ecommerce.Common.Context.CartContext = null; if (page.Item["ContextCart"] != null) { var orderContext = Dynamicweb.Ecommerce.Services.OrderContexts.GetOrderContextById(page.Item["ContextCart"].ToString()); Dynamicweb.Ecommerce.Common.Context.CartContext = orderContext; } if (Dynamicweb.Ecommerce.Common.Context.Cart != null) { bool renderOrderlineCountInsteadOfProductCount = page.Item["RenderOrderlineCountInsteadOfProductCount"] != null ? Convert.ToBoolean(page.Item["RenderOrderlineCountInsteadOfProductCount"]) : false; if (!renderOrderlineCountInsteadOfProductCount) { totalProducts = Dynamicweb.Ecommerce.Common.Context.Cart.GetParentProductLineQuantityCount(Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines); } else { totalProducts = Dynamicweb.Ecommerce.Common.Context.Cart.GetParentOrderLineCount(Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines); } } switch (layout) { case "linksOnly": <span class="align-middle">@node.Name</span> <span class="@jsCartClass mini-cart-quantity align-middle" @cartId>(@totalProducts)</span> break; case "iconsOnly": {@RenderIcon(pageIcon, iconSize)} <span class="@jsCartClass mini-cart-quantity align-middle" @cartId>(@totalProducts)</span> break; case "iconsAndLinks": {@RenderIcon(pageIcon, iconSize)} <span class="@jsCartClass mini-cart-quantity align-middle" @cartId>(@totalProducts)</span> <span class="align-middle">@node.Name</span> break; case "linksAndIcons": <span class="align-middle">@node.Name</span> <span class="@jsCartClass mini-cart-quantity align-middle" @cartId>(@totalProducts)</span> {@RenderIcon(pageIcon, iconSize)} break; } } else { string name = node.Name; if (preferencesType == "country") { //Country name = Translate("Deliver to") + ": " + Dynamicweb.Ecommerce.Common.Context.Country.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID); } if (preferencesType == "language") { //Languange string iconFolder = "/Files/FlagIcons/"; pageIcon = iconFolder + Pageview.Area.CultureInfo.Name.ToLower() + ".svg"; Regex reg = new Regex(@"\(([^\)]+)\)"); name = reg.Replace(Pageview.Area.CultureInfo.DisplayName, ""); layout = layout == "linksOnly" ? "iconsAndLinks" : layout; bool hideIcon = page.Item?["HideIcon"] != null ? Convert.ToBoolean(page.Item["HideIcon"].ToString()) : false; bool hideName = page.Item?["HideName"] != null ? Convert.ToBoolean(page.Item["HideName"].ToString()) : false; layout = hideIcon ? "linksOnly" : layout; layout = hideName ? "iconsOnly" : layout; } if (preferencesType == "currency") { //Country name = Dynamicweb.Ecommerce.Common.Context.Currency.Code; } switch (layout) { case "linksOnly": <span class="align-middle">@name</span> break; case "iconsOnly": <span class="visually-hidden">@name</span> {@RenderIcon(pageIcon, iconSize)} break; case "iconsAndLinks": {@RenderIcon(pageIcon, iconSize)} <span class="align-middle">@name</span> break; case "linksAndIcons": <span class="align-middle">@name</span> {@RenderIcon(pageIcon, iconSize)} break; } } } @helper RenderPreferencesDropdown(Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel node, string preferencesType, string linkFontSize, string linkFontWeight, string linkCasing, string theme, string pageType, string pageIcon, string iconSize, string layout) { string groupId = Dynamicweb.Context.Current.Request["GroupID"] != null ? Dynamicweb.Context.Current.Request["GroupID"].ToString() : ""; string productId = Dynamicweb.Context.Current.Request["ProductID"] != null ? Dynamicweb.Context.Current.Request["ProductID"].ToString() : ""; string variantId = Dynamicweb.Context.Current.Request["VariantID"] != null ? Dynamicweb.Context.Current.Request["VariantID"].ToString() : ""; int currentParagraphId = Pageview.CurrentParagraph.ID; string nodeId = !string.IsNullOrEmpty(node.GroupId) ? "PreferencesLink_" + node.GroupId + "_" + currentParagraphId : "PreferencesLink_" + node.PageId.ToString() + "_" + currentParagraphId; <li class="nav-item dropdown"> <form class="d-none d-lg-block" action="/Default.aspx?ID=@node.PageId" data-response-target-element="@(preferencesType)Dropdown_@currentParagraphId" data-layout-template="Swift_Preferences.cshtml" data-preloader="inline"> <input type="hidden" name="Type" value="@preferencesType"> <input type="hidden" name="CurrentPageID" value="@Pageview.ID"> <input type="hidden" name="GroupID" value="@groupId"> <input type="hidden" name="ProductID" value="@productId"> <input type="hidden" name="VariantID" value="@variantId"> <input type="hidden" name="FontSize" value="@linkFontSize"> <input type="hidden" name="FontWeight" value="@linkFontWeight"> <input type="hidden" name="Casing" value="@linkCasing"> <a id="@nodeId" onmouseover="swift.PageUpdater.Update(event)" onclick="swift.PageUpdater.Update(event)" class="nav-link p-2 text-nowrap text-decoration-underline-hover @linkFontSize @linkFontWeight @linkCasing@(node.IsActive ? " active" : "") dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @(node.IsActive ? " aria-current='page'" : "")> @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout, preferencesType)} </a> <ul class="dropdown-menu @(theme)" id="@(preferencesType)Dropdown_@currentParagraphId"> @* The content here comes from an external request *@ </ul> </form> <form class="d-block d-lg-none" action="/Default.aspx?ID=@node.PageId" data-response-target-element="PreferencesModalContent" data-layout-template="Swift_Preferences.cshtml" data-preloader="inline"> <input type="hidden" name="Layout" value="modal"> <input type="hidden" name="CurrentPageID" value="@Pageview.ID"> <input type="hidden" name="GroupID" value="@groupId"> <input type="hidden" name="ProductID" value="@productId"> <input type="hidden" name="VariantID" value="@variantId"> <button type="button" onmouseover="swift.PageUpdater.Update(event)" onclick="swift.PageUpdater.Update(event)" class="btn nav-link p-2 text-nowrap border-0 swift_open-preferences-modal @linkFontSize @linkFontWeight @linkCasing" data-bs-toggle="modal" data-bs-target="#PreferencesModal"> @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout, preferencesType)} </button> </form> </li> } @helper RenderIcon(string pageIcon, string iconSize) { if (pageIcon.EndsWith(".svg", StringComparison.OrdinalIgnoreCase) && !pageIcon.EndsWith("none.svg", StringComparison.OrdinalIgnoreCase)) { string iconPath = Dynamicweb.Context.Current.Server.MapPath(pageIcon); <span class="@iconSize"> @ReadFile(iconPath) </span> } } @helper RenderSubNodes(Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel subnode , int maxLevel , string nodeId , int count) { <li class="nav-item@(subnode.Nodes.Any() ? " dropdown" : "") d-flex align-items-center"> @if (subnode.IsClickable) { <a href="@subnode.Link" class="dropdown-item py-2 text-decoration-underline-hover" @(subnode.IsActive ? " aria-current='page'" : "") id="@nodeId">@subnode.Name</a> if (subnode.Nodes.Any() && (count != maxLevel)) { <ul class="dropdown-menu dropdown-submenu" aria-labelledby="@nodeId"> @foreach (var item in subnode.Nodes) { if (item.Nodes.Any()) { count++; @RenderSubNodes(item , 2 , nodeId , count) } else { <li class="d-flex align-items-center"> <a href="@item.Link" class="dropdown-item py-2 text-decoration-underline-hover" title="@item.Name">@item.Name</a> </li> } } </ul> <span class="px-2 lh-1 arrow_wrapper"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg> </span> } } else { <span class="dropdown-item py-2" @(subnode.IsActive ? " aria-current='page'" : "") id="@nodeId">@subnode.Name</span> } </li> }
The Directions Calendar

Here is you session overview of Directions ASIA 2023

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum

Keynote

Some description of the keynote

08:30 - 11:40
Break, Networking

You can do whatever you like

11:30 - 12:40
General sessions
12:40 - 18:30
Keynote
08:30 - 11:30
What can you look forward to?

The speakerwall for Directions EMEA 2023

What can you look forward to?

The speakerwall for Directions EMEA 2023

Want a sneak peak?

What will you learn?

If you want to connect with other partners, have a front-row seat to learn about the newest releases, share information with other Business Decision-makers, or simply grow together with the Dynamics 365 community, attending Directions ASIA is a no brainer. 

Directions4Partners are gathering the Microsoft teams and best of the industry to come and teach you all the latest information in-person