/// <summary>
        /// Gets the CMS Page using Dynamic Routing, returning the culture variation that either matches the given culture or the Slug's culture, or the default site culture if not found.
        /// </summary>
        /// <param name="Url">The Url (part after the domain), if empty will use the Current Request</param>
        /// <param name="Culture">The Culture, not needed if the Url contains the culture that the UrlSlug has as part of it's generation.</param>
        /// <param name="SiteName">The Site Name, defaults to current site.</param>
        /// <param name="Columns">List of columns you wish to include in the data returned.</param>
        /// <param name="AddPageToCacheDependency">If true, the found page will have it's DocumentID added to the request's Output Cache Dependency</param>
        /// <returns>The Page that matches the Url Slug, for the given or matching culture (or default culture if one isn't found).</returns>
        public ITreeNode GetPage(string Url = "", string Culture = "", string SiteName = "", IEnumerable <string> Columns = null, bool AddPageToCacheDependency = true)
        {
            // Load defaults
            SiteName = (!string.IsNullOrWhiteSpace(SiteName) ? SiteName : DynamicRouteInternalHelper.SiteContextSafe().SiteName);
            string DefaultCulture = DynamicRouteInternalHelper.SiteContextSafe().DefaultVisitorCulture;

            if (string.IsNullOrWhiteSpace(Url))
            {
                Url = EnvironmentHelper.GetUrl(HttpContext.Current.Request.Url.AbsolutePath, HttpContext.Current.Request.ApplicationPath, SiteName);
            }

            // Handle Preview, during Route Config the Preview isn't available and isn't really needed, so ignore the thrown exception
            bool PreviewEnabled = false;

            try
            {
                PreviewEnabled = HttpContext.Current.Kentico().Preview().Enabled;
            }
            catch (InvalidOperationException) { }

            GetCultureEventArgs CultureArgs = new GetCultureEventArgs()
            {
                DefaultCulture = DefaultCulture,
                SiteName       = SiteName,
                Request        = HttpContext.Current.Request,
                PreviewEnabled = PreviewEnabled,
                Culture        = Culture
            };

            using (var DynamicRoutingGetCultureTaskHandler = DynamicRoutingEvents.GetCulture.StartEvent(CultureArgs))
            {
                // If Preview is enabled, use the Kentico Preview CultureName
                if (PreviewEnabled && string.IsNullOrWhiteSpace(CultureArgs.Culture))
                {
                    try
                    {
                        CultureArgs.Culture = HttpContext.Current.Kentico().Preview().CultureName;
                    }
                    catch (Exception) { }
                }

                // If culture still not set, use the LocalizationContext.CurrentCulture
                if (string.IsNullOrWhiteSpace(CultureArgs.Culture))
                {
                    try
                    {
                        CultureArgs.Culture = LocalizationContext.CurrentCulture.CultureCode;
                    }
                    catch (Exception) { }
                }

                // If that fails then use the System.Globalization.CultureInfo
                if (string.IsNullOrWhiteSpace(CultureArgs.Culture))
                {
                    try
                    {
                        CultureArgs.Culture = System.Globalization.CultureInfo.CurrentCulture.Name;
                    }
                    catch (Exception) { }
                }

                DynamicRoutingGetCultureTaskHandler.FinishEvent();
            }

            // set the culture
            Culture = CultureArgs.Culture;

            // Convert Columns to string, must include DocumentID though at all times
            if (Columns != null && !Columns.Contains("*") && !Columns.Contains("documentid", StringComparer.InvariantCultureIgnoreCase))
            {
                var Appended = Columns.ToList();
                Appended.Add("documentid");
                Columns = Appended;
            }
            string ColumnsVal = Columns != null?string.Join(",", Columns.Distinct()) : "*";

            // Create GetPageEventArgs Event ARgs
            GetPageEventArgs Args = new GetPageEventArgs()
            {
                RelativeUrl    = Url,
                Culture        = Culture,
                DefaultCulture = DefaultCulture,
                SiteName       = SiteName,
                PreviewEnabled = PreviewEnabled,
                ColumnsVal     = ColumnsVal,
                Request        = HttpContext.Current.Request
            };

            // Run any GetPage Event hooks which allow the users to set the Found Page
            ITreeNode FoundPage = null;

            using (var DynamicRoutingGetPageTaskHandler = DynamicRoutingEvents.GetPage.StartEvent(Args))
            {
                if (Args.FoundPage == null)
                {
                    try
                    {
                        Args.FoundPage = CacheHelper.Cache <TreeNode>(cs =>
                        {
                            // Using custom query as Kentico's API was not properly handling a Join and where.
                            DataTable NodeTable = ConnectionHelper.ExecuteQuery("DynamicRouting.UrlSlug.GetDocumentsByUrlSlug", new QueryDataParameters()
                            {
                                { "@Url", Url },
                                { "@Culture", Culture },
                                { "@DefaultCulture", DefaultCulture },
                                { "@SiteName", SiteName }
                            }, topN: 1, columns: "DocumentID, ClassName").Tables[0];
                            if (NodeTable.Rows.Count > 0)
                            {
                                int DocumentID   = ValidationHelper.GetInteger(NodeTable.Rows[0]["DocumentID"], 0);
                                string ClassName = ValidationHelper.GetString(NodeTable.Rows[0]["ClassName"], "");

                                DocumentQuery Query = DocumentHelper.GetDocuments(ClassName)
                                                      .WhereEquals("DocumentID", DocumentID)
                                                      .CombineWithAnyCulture();

                                // Handle Columns
                                if (!string.IsNullOrWhiteSpace(ColumnsVal))
                                {
                                    Query.Columns(ColumnsVal);
                                }

                                // Handle Preview
                                if (PreviewEnabled)
                                {
                                    Query.LatestVersion(true)
                                    .Published(false);
                                }
                                else
                                {
                                    Query.Published();
                                }

                                TreeNode Page = Query.FirstOrDefault();

                                // Cache dependencies on the Url Slugs and also the DocumentID if available.
                                if (cs.Cached)
                                {
                                    cs.CacheDependency = CacheHelper.GetCacheDependency(new string[] {
                                        "dynamicrouting.urlslug|all",
                                        "documentid|" + DocumentID
                                    });
                                }

                                // Return Page Data
                                return(Query.FirstOrDefault());
                            }
                            else
                            {
                                return(null);
                            }
                        }, new CacheSettings((PreviewEnabled ? 0 : 1440), "DynamicRoutine.GetPage", Url, Culture, DefaultCulture, SiteName, PreviewEnabled, ColumnsVal));
                    }
                    catch (Exception ex)
                    {
                        // Add exception so they can handle
                        DynamicRoutingGetPageTaskHandler.EventArguments.ExceptionOnLookup = ex;
                    }
                }

                // Finish event, this will trigger the After
                DynamicRoutingGetPageTaskHandler.FinishEvent();

                // Return whatever Found Page
                FoundPage = DynamicRoutingGetPageTaskHandler.EventArguments.FoundPage;
            }

            // Add documentID to the output cache dependencies, we ensured that DocumentID would be returned in the result always.
            if (FoundPage != null && AddPageToCacheDependency && HttpContext.Current != null && HttpContext.Current.Response != null)
            {
                string Key = $"documentid|{FoundPage.DocumentID}";
                CacheHelper.EnsureDummyKey(Key);
                HttpContext.Current.Response.AddCacheItemDependency(Key);
            }

            return(FoundPage);
        }
        /// <summary>
        /// Can override this if you need to implement custom logic, such as a custom route.  httpContext.Request.RequestContext.RouteData.Values is often used to grab route data.
        /// </summary>
        /// <param name="httpContext">The HttpContext of the request</param>
        /// <returns>The Tree Node for this request, null acceptable.</returns>
        private TreeNode GetTreeNode(HttpContextBase httpContext)
        {
            TreeNode FoundNode      = null;
            string   SiteName       = SiteContextSafe().SiteName;
            string   DefaultCulture = SiteContextSafe().DefaultVisitorCulture;
            // Create GetPage Event Arguments
            GetPageEventArgs PageArgs = new GetPageEventArgs()
            {
                RelativeUrl    = GetUrl(httpContext.Request.Url.AbsolutePath, httpContext.Request.ApplicationPath, SiteName),
                HttpContext    = httpContext,
                SiteName       = SiteName,
                Culture        = GetCulture(),
                DefaultCulture = DefaultCulture
            };

            // Start event, allow user to overwrite FoundPage
            using (var KenticoAuthorizeGetPageTaskHandler = AuthorizeEvents.GetPage.StartEvent(PageArgs))
            {
                if (PageArgs.FoundPage == null)
                {
                    IPageDataContextRetriever PageContextRetriever = DependencyResolver.Current.GetService <IPageDataContextRetriever>();
                    var PageContext = PageContextRetriever.Retrieve <TreeNode>();

                    // Try using Kentico's Page Builder Data Context
                    if (PageContext != null && PageContext.Page != null)
                    {
                        PageArgs.FoundPage = PageContext.Page;
                    }
                    else
                    {
                        try
                        {
                            // Try to find the page from node alias path, default lookup type
                            PageArgs.FoundPage = CacheHelper.Cache(cs =>
                            {
                                TreeNode Page = DocumentHelper.GetDocuments()
                                                .Path(PageArgs.RelativeUrl, PathTypeEnum.Single)
                                                .Culture(!string.IsNullOrWhiteSpace(PageArgs.Culture) ? PageArgs.Culture : PageArgs.DefaultCulture)
                                                .CombineWithAnyCulture()
                                                .CombineWithDefaultCulture()
                                                .OnSite(PageArgs.SiteName)
                                                .Columns("NodeACLID", "NodeID", "DocumentID", "DocumentCulture") // The Fields required for authorization
                                                .FirstOrDefault();

                                if (cs.Cached && Page != null)
                                {
                                    cs.CacheDependency = CacheHelper.GetCacheDependency(new string[]
                                    {
                                        $"nodeid|{Page.NodeID}",
                                        $"documentid|{Page.DocumentID}"
                                    });
                                }
                                return(Page);
                            }, new CacheSettings(1440, "KenticoAuthorizeGetTreeNode", PageArgs.RelativeUrl, PageArgs.SiteName));
                        }
                        catch (Exception ex)
                        {
                            PageArgs.ExceptionOnLookup = ex;
                        }
                    }
                }
                else if (PageArgs.FoundPage.NodeACLID <= 0)
                {
                    PageArgs.ExceptionOnLookup = new NullReferenceException("The TreeNode does not contain the NodeACLID property, which is required for Permission lookup.");
                }

                // Finish the event
                KenticoAuthorizeGetPageTaskHandler.FinishEvent();

                // Pass the Found Node back from the args
                FoundNode = PageArgs.FoundPage;
            }

            return(PageArgs.FoundPage);
        }
示例#3
0
        public static void OverrideGetPageEvent(object sender, GetPageEventArgs args)
        {
            string cultureCode = args.Culture;

            //Occasionally the culture code may come out as full text such as English - United Kingdom, using this info we can fetch the culture code
            if (args.Culture.Length > 5)
            {
                cultureCode = CultureInfoProvider.GetCultures().Where(a => a.CultureName == args.Culture).First().CultureCode;
            }
            UpdateCacheItem <string>("CurrentRelUrl", args.RelativeUrl);
            UpdateCacheItem <string>("CultureCode", cultureCode);
            if (args.FoundPage == null)
            {
                try
                {
                    args.FoundPage = CacheHelper.Cache <TreeNode>(cs =>
                    {
                        //TODO: ADD Culture
                        DataTable PossibleUrlPatterns = GetPossibleUrls(args.RelativeUrl, cultureCode);
                        if (PossibleUrlPatterns.Rows.Count > 0)
                        {
                            var matchedUrl = GetUrlMatch(args.RelativeUrl, cultureCode, PossibleUrlPatterns);
                            if (matchedUrl == null || !matchedUrl.HasMatch)
                            {
                                return(null);
                            }
                            DocumentQuery Query = DocumentHelper.GetDocuments(matchedUrl.UrlBreakdown.KenticoData.ClassName).WhereEquals("NodeId", matchedUrl.UrlBreakdown.KenticoData.NodeId).CombineWithAnyCulture();

                            if (args.PreviewEnabled)
                            {
                                Query.LatestVersion(true).Published(false);
                            }
                            else
                            {
                                Query.PublishedVersion(true);
                            }

                            TreeNode page = Query.FirstOrDefault();

                            if (cs.Cached)
                            {
                                if (page != null)
                                {
                                    cs.CacheDependency = CacheHelper.GetCacheDependency(new string[] { $"{WildcardUrlInfo.OBJECT_TYPE}|all", "documentid|" + page.DocumentID });
                                }
                                else
                                {
                                    cs.CacheDependency = CacheHelper.GetCacheDependency(new string[] { $"{WildcardUrlInfo.OBJECT_TYPE}dynamicrouting.wildcards|all" });
                                }
                            }
                            return(page);
                        }
                        else
                        {
                            return(null);
                        }
                    }, new CacheSettings(args.PreviewEnabled ? 0 : 1440, "DynamicRouting.GetPage", args.RelativeUrl, cultureCode, args.DefaultCulture, args.SiteName, args.PreviewEnabled, args.ColumnsVal));
                }
                catch (Exception ex)
                {
                    args.ExceptionOnLookup = ex;
                }
                if (args.FoundPage == null)
                {
                    HttpContext.Current.Response.StatusCode = 404;
                }
            }
        }
示例#4
0
        /// <summary>
        /// Gets the CMS Page using Dynamic Routing, returning the culture variation that either matches the given culture or the Slug's culture, or the default site culture if not found.
        /// </summary>
        /// <param name="Url">The Url (part after the domain), if empty will use the Current Request</param>
        /// <param name="Culture">The Culture, not needed if the Url contains the culture that the UrlSlug has as part of it's generation.</param>
        /// <param name="SiteName">The Site Name, defaults to current site.</param>
        /// <param name="Columns">List of columns you wish to include in the data returned.</param>
        /// <returns>The Page that matches the Url Slug, for the given or matching culture (or default culture if one isn't found).</returns>
        public static ITreeNode GetPage(string Url = "", string Culture = "", string SiteName = "", IEnumerable <string> Columns = null)
        {
            // Load defaults
            SiteName = (!string.IsNullOrWhiteSpace(SiteName) ? SiteName : DynamicRouteInternalHelper.SiteContextSafe().SiteName);
            string DefaultCulture = DynamicRouteInternalHelper.SiteContextSafe().DefaultVisitorCulture;

            if (string.IsNullOrWhiteSpace(Url))
            {
                Url = EnvironmentHelper.GetUrl(HttpContext.Current.Request.Url.AbsolutePath, HttpContext.Current.Request.ApplicationPath, SiteName);
            }

            // Handle Preview, during Route Config the Preview isn't available and isn't really needed, so ignore the thrown exception
            bool PreviewEnabled = false;

            try
            {
                PreviewEnabled = PortalContext.ViewMode != ViewModeEnum.LiveSite;
            }
            catch (InvalidOperationException) { }

            GetCultureEventArgs CultureArgs = new GetCultureEventArgs()
            {
                DefaultCulture = DefaultCulture,
                SiteName       = SiteName,
                Request        = HttpContext.Current.Request,
                PreviewEnabled = PreviewEnabled,
                Culture        = Culture
            };

            using (var DynamicRoutingGetCultureTaskHandler = DynamicRoutingEvents.GetCulture.StartEvent(CultureArgs))
            {
                // If culture not set, use the LocalizationContext.CurrentCulture
                if (string.IsNullOrWhiteSpace(CultureArgs.Culture))
                {
                    try
                    {
                        CultureArgs.Culture = LocalizationContext.CurrentCulture.CultureName;
                    }
                    catch (Exception) { }
                }

                // if that fails then use the System.Globalization.CultureInfo
                if (string.IsNullOrWhiteSpace(CultureArgs.Culture))
                {
                    try
                    {
                        CultureArgs.Culture = System.Globalization.CultureInfo.CurrentCulture.Name;
                    }
                    catch (Exception) { }
                }

                DynamicRoutingGetCultureTaskHandler.FinishEvent();
            }

            // set the culture
            Culture = CultureArgs.Culture;

            // Convert Columns to
            string ColumnsVal = Columns != null?string.Join(",", Columns.Distinct()) : "*";

            // Create GetPageEventArgs Event ARgs
            GetPageEventArgs Args = new GetPageEventArgs()
            {
                RelativeUrl    = Url,
                Culture        = Culture,
                DefaultCulture = DefaultCulture,
                SiteName       = SiteName,
                PreviewEnabled = PreviewEnabled,
                ColumnsVal     = ColumnsVal,
                Request        = HttpContext.Current.Request
            };

            // Run any GetPage Event hooks which allow the users to set the Found Page
            ITreeNode FoundPage = null;

            using (var DynamicRoutingGetPageTaskHandler = DynamicRoutingEvents.GetPage.StartEvent(Args))
            {
                if (Args.FoundPage == null)
                {
                    try
                    {
                        // Get Page based on Url
                        Args.FoundPage = CacheHelper.Cache <TreeNode>(cs =>
                        {
                            // Using custom query as Kentico's API was not properly handling a Join and where.
                            DataTable NodeTable = ConnectionHelper.ExecuteQuery("DynamicRouting.UrlSlug.GetDocumentsByUrlSlug", new QueryDataParameters()
                            {
                                { "@Url", Url },
                                { "@Culture", Culture },
                                { "@DefaultCulture", DefaultCulture },
                                { "@SiteName", SiteName },
                                { "@PreviewEnabled", PreviewEnabled }
                            }, topN: 1, columns: "DocumentID, ClassName").Tables[0];
                            if (NodeTable.Rows.Count > 0)
                            {
                                int DocumentID   = ValidationHelper.GetInteger(NodeTable.Rows[0]["DocumentID"], 0);
                                string ClassName = ValidationHelper.GetString(NodeTable.Rows[0]["ClassName"], "");

                                DocumentQuery Query = DocumentHelper.GetDocuments(ClassName)
                                                      .WhereEquals("DocumentID", DocumentID);

                                // Handle Columns
                                if (!string.IsNullOrWhiteSpace(ColumnsVal))
                                {
                                    Query.Columns(ColumnsVal);
                                }

                                // Handle Preview
                                if (PreviewEnabled)
                                {
                                    Query.LatestVersion(true)
                                    .Published(false);
                                }
                                else
                                {
                                    Query.PublishedVersion(true);
                                }

                                TreeNode Page = Query.FirstOrDefault();

                                // Cache dependencies on the Url Slugs and also the DocumentID if available.
                                if (cs.Cached)
                                {
                                    if (Page != null)
                                    {
                                        cs.CacheDependency = CacheHelper.GetCacheDependency(new string[] {
                                            "dynamicrouting.urlslug|all",
                                            "dynamicrouting.versionhistoryurlslug|all",
                                            "dynamicrouting.versionhistoryurlslug|bydocumentid|" + Page.DocumentID,
                                            "documentid|" + Page.DocumentID,
                                        });
                                    }
                                    else
                                    {
                                        cs.CacheDependency = CacheHelper.GetCacheDependency(new string[] { "dynamicrouting.urlslug|all", "dynamicrouting.versionhistoryurlslug|all" });
                                    }
                                }

                                // Return Page Data
                                return(Query.FirstOrDefault());
                            }
                            else
                            {
                                return(null);
                            }
                        }, new CacheSettings(1440, "DynamicRoutine.GetPage", Url, Culture, DefaultCulture, SiteName, PreviewEnabled, ColumnsVal));
                    }
                    catch (Exception ex)
                    {
                        // Add exception so they can handle
                        DynamicRoutingGetPageTaskHandler.EventArguments.ExceptionOnLookup = ex;
                    }
                }

                // Finish event, this will trigger the After
                DynamicRoutingGetPageTaskHandler.FinishEvent();

                // Return whatever Found Page
                FoundPage = DynamicRoutingGetPageTaskHandler.EventArguments.FoundPage;
            }
            return(FoundPage);
        }
 public Task <TreeNode> GetCustomPageAsync(GetPageEventArgs pageArgs, AuthorizationEventType eventType)
 {
     return(Task.FromResult <TreeNode>(null));
 }
示例#6
0
        public async Task <TreeNode> GetCurrentPageAsync()
        {
            TreeNode foundNode      = null;
            string   SiteName       = SiteContextSafe().SiteName;
            string   DefaultCulture = SiteContextSafe().DefaultVisitorCulture;

            // Create GetPage Event Arguments
            GetPageEventArgs pageArgs = new GetPageEventArgs()
            {
                RelativeUrl    = GetUrl(UriHelper.GetDisplayUrl(_httpContext.Request), (_httpContext.Request.PathBase.HasValue ? _httpContext.Request.PathBase.Value : ""), SiteName),
                HttpContext    = _httpContext,
                SiteName       = SiteName,
                Culture        = await GetCultureAsync(),
                DefaultCulture = DefaultCulture
            };

            var customTreeNode = await _authorizationContextCustomizer.GetCustomPageAsync(pageArgs, AuthorizationEventType.Before);

            if (customTreeNode != null)
            {
                if (customTreeNode.NodeACLID <= 0)
                {
                    throw new NullReferenceException("The TreeNode does not contain the NodeACLID property, which is required for Permission lookup.");
                }
                foundNode = customTreeNode;
            }

            if (foundNode == null)
            {
                // Try to find the page from node alias path, default lookup type

                try
                {
                    if (_pageDataContextRetriever.TryRetrieve <TreeNode>(out var pageContext))
                    {
                        foundNode = pageContext.Page;
                    }
                }
                catch (InvalidOperationException)
                {
                    // this may be thrown for invalid pages or internal requests
                }
                if (foundNode == null)
                {
                    foundNode = await _progressiveCache.LoadAsync(async cs =>
                    {
                        var pages = await DocumentHelper.GetDocuments()
                                    .Path(pageArgs.RelativeUrl, PathTypeEnum.Single)
                                    .Culture(!string.IsNullOrWhiteSpace(pageArgs.Culture) ? pageArgs.Culture : pageArgs.DefaultCulture)
                                    .CombineWithAnyCulture()
                                    .CombineWithDefaultCulture()
                                    .OnSite(pageArgs.SiteName)
                                    .Columns("NodeACLID", "NodeID", "DocumentID", "DocumentCulture") // The Fields required for authorization
                                    .GetEnumerableTypedResultAsync();

                        var pageList = pages.ToList();
                        var page     = pageList.FirstOrDefault();
                        if (cs.Cached && pageList.Any())
                        {
                            cs.CacheDependency = CacheHelper.GetCacheDependency(new string[]
                            {
                                $"nodeid|{page.NodeID}",
                                $"documentid|{page.DocumentID}"
                            });
                        }
                        return(page);
                    }, new CacheSettings(1440, "KenticoAuthorizeGetTreeNode", pageArgs.RelativeUrl, pageArgs.SiteName));
                }

                pageArgs.FoundPage = foundNode;
                var customTreeNodeAfter = await _authorizationContextCustomizer.GetCustomPageAsync(pageArgs, AuthorizationEventType.After);

                if (customTreeNodeAfter != null)
                {
                    if (customTreeNode.NodeACLID <= 0)
                    {
                        new NullReferenceException("The TreeNode does not contain the NodeACLID property, which is required for Permission lookup.");
                    }
                    foundNode = pageArgs.FoundPage;
                }
            }

            return(foundNode);
        }