/// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGrid()
        {
            using (var rockContext = new RockContext())
            {
                var pageShortLinkService = new PageShortLinkService(rockContext);

                var qry = pageShortLinkService.Queryable().ToList()
                          .Select(s => new ShortLinkRow(s))
                          .ToList()
                          .AsQueryable();


                SortProperty sortProperty = gShortLinks.SortProperty;
                if (sortProperty != null)
                {
                    gShortLinks.DataSource = qry.Sort(sortProperty).ToList();
                }
                else
                {
                    gShortLinks.DataSource = qry.OrderBy(l => l.Token).ToList();
                }

                gShortLinks.DataBind();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles the Click event of the DeleteShortLink control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param>
        protected void DeleteShortLink_Click(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            bool canDelete = false;

            var rockContext = new RockContext();
            PageShortLinkService pageShortLinkService = new PageShortLinkService(rockContext);

            var shortLink = pageShortLinkService.Get(e.RowKeyId);

            if (shortLink != null)
            {
                string errorMessage;
                canDelete = pageShortLinkService.CanDelete(shortLink, out errorMessage);
                if (!canDelete)
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Alert);
                    return;
                }

                int siteId = shortLink.SiteId;

                pageShortLinkService.Delete(shortLink);
                rockContext.SaveChanges();
            }

            BindGrid();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="shortLinkId">The shortLink identifier.</param>
        /// <param name="siteId">The group id.</param>
        public void ShowDetail(int shortLinkId)
        {
            PageShortLink shortLink = null;

            if (!shortLinkId.Equals(0))
            {
                shortLink = new PageShortLinkService(new RockContext()).Get(shortLinkId);
                pdAuditDetails.SetEntity(shortLink, ResolveRockUrl("~"));
            }

            if (shortLink == null)
            {
                shortLink = new PageShortLink {
                    Id = 0
                };

                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            hfShortLinkId.Value = shortLink.Id.ToString();

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(Rock.Model.PageShortLink.FriendlyTypeName);
            }

            if (readOnly)
            {
                btnEdit.Visible = false;
                //btnDelete.Visible = false;
                ShowReadonlyDetails(shortLink);
            }
            else
            {
                btnEdit.Visible = true;
                //btnDelete.Visible = !shortLink.IsSystem;
                if (shortLink.Id > 0)
                {
                    ShowReadonlyDetails(shortLink);
                }
                else
                {
                    ShowEditDetails(shortLink);
                }
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Handles the Click event of the btnCancel control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
 protected void btnCancel_Click(object sender, EventArgs e)
 {
     if (hfShortLinkId.Value.Equals("0"))
     {
         // Cancelling on Add
         NavigateToParentPage();
     }
     else
     {
         // Cancelling on Edit
         var shortLink = new PageShortLinkService(new RockContext()).Get(int.Parse(hfShortLinkId.Value));
         ShowReadonlyDetails(shortLink);
     }
 }
Ejemplo n.º 5
0
        protected void btnDelete_Click(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var service = new PageShortLinkService(rockContext);
                var link    = service.Get(hfShortLinkId.ValueAsInt());
                if (link != null)
                {
                    service.Delete(link);
                    rockContext.SaveChanges();

                    NavigateToParentPage();
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGrid()
        {
            using (var rockContext = new RockContext())
            {
                var pageShortLinkService = new PageShortLinkService(rockContext);

                var shortLinkQry = pageShortLinkService.Queryable();

                string token = gfShortLink.GetUserPreference(FilterAttributeKeys.Token);
                if (!string.IsNullOrEmpty(token))
                {
                    shortLinkQry = shortLinkQry.Where(s => s.Token.Contains(token));
                }

                int?siteId = gfShortLink.GetUserPreference(FilterAttributeKeys.Site).AsIntegerOrNull();
                if (siteId.HasValue)
                {
                    shortLinkQry = shortLinkQry.Where(s => s.SiteId == siteId.Value);
                }


                var qry = shortLinkQry.ToList()
                          .Select(s => new ShortLinkRow(s))
                          .ToList()
                          .AsQueryable();

                SortProperty sortProperty = gShortLinks.SortProperty;
                if (sortProperty != null)
                {
                    gShortLinks.DataSource = qry.Sort(sortProperty).ToList();
                }
                else
                {
                    gShortLinks.DataSource = qry.OrderBy(l => l.Token).ToList();
                }

                gShortLinks.DataBind();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        /// <param name="message"></param>
        public override void Execute(Message message)
        {
            var rockContext   = new RockContext();
            var pageShortLink = new PageShortLinkService(rockContext).Get(message.PageShortLinkId);

            if (pageShortLink == null)
            {
                return;
            }

            var userAgent = (message.UserAgent ?? string.Empty).Trim();

            if (userAgent.Length > 450)
            {
                userAgent = userAgent.Substring(0, 450);   // trim super long useragents to fit in pageViewUserAgent.UserAgent
            }

            // get user agent info
            var clientType = InteractionDeviceType.GetClientType(userAgent);

            // don't log visits from crawlers
            if (clientType != "Crawler")
            {
                // lookup the interaction channel, and create it if it doesn't exist
                int channelMediumTypeValueId = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_URLSHORTENER.AsGuid()).Id;
                InteractionChannelService interactionChannelService = new InteractionChannelService(rockContext);
                var interactionChannel = interactionChannelService.Queryable()
                                         .Where(a => a.ChannelTypeMediumValueId == channelMediumTypeValueId)
                                         .FirstOrDefault();
                if (interactionChannel == null)
                {
                    interactionChannel      = new InteractionChannel();
                    interactionChannel.Name = "Short Links";
                    interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                    interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Get <Rock.Model.PageShortLink>().Id;
                    interactionChannel.Guid = SystemGuid.InteractionChannel.SHORT_LINKS.AsGuid();
                    interactionChannelService.Add(interactionChannel);
                    rockContext.SaveChanges();
                }

                // check that the page exists as a component
                var interactionComponent = new InteractionComponentService(rockContext).GetComponentByChannelIdAndEntityId(interactionChannel.Id, pageShortLink.Id, message.Token);
                if (message.Url.IsNotNullOrWhiteSpace())
                {
                    if (interactionComponent.ComponentSummary != message.Url)
                    {
                        interactionComponent.ComponentSummary = message.Url;
                    }

                    var urlDataJson = new { Url = message.Url }.ToJson();
                    if (interactionComponent.ComponentData != urlDataJson)
                    {
                        interactionComponent.ComponentData = urlDataJson;
                    }
                }

                rockContext.SaveChanges();

                // Add the interaction
                if (interactionComponent != null)
                {
                    int?personAliasId = null;
                    if (message.UserName.IsNotNullOrWhiteSpace())
                    {
                        var currentUser = new UserLoginService(rockContext).GetByUserName(message.UserName);
                        personAliasId = currentUser?.Person?.PrimaryAlias?.Id;
                    }

                    Parser     uaParser      = Parser.GetDefault();
                    ClientInfo client        = uaParser.Parse(userAgent);
                    var        clientOs      = client.OS.ToString();
                    var        clientBrowser = client.UA.ToString();

                    new InteractionService(rockContext).AddInteraction(interactionComponent.Id, null, "View", message.Url, personAliasId, message.DateViewed, clientBrowser, clientOs, clientType, userAgent, message.IPAddress, message.SessionId?.AsGuidOrNull());
                    rockContext.SaveChanges();
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Determine the logical page being requested by evaluating the routedata, or querystring and
        /// then loading the appropriate layout (ASPX) page
        ///
        /// Pick url on the following priority order:
        /// 1. PageId
        /// 2. Route match and site match
        /// 3. ShortLink match and site match
        /// 4. Route and no site match
        /// 5. ShortLink with no site match
        /// 6. If there is no routing info in the request then set to default page
        /// 7. 404 if route does not exist
        ///
        /// </summary>
        /// <param name="requestContext"></param>
        /// <returns></returns>
        System.Web.IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            string pageId      = string.Empty;
            int    routeId     = 0;
            bool   isSiteMatch = false;
            Dictionary <string, string> parms;
            string          host;
            HttpRequestBase routeHttpRequest;
            HttpCookie      siteCookie;

            // Context cannot be null
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }

            try
            {
                routeHttpRequest = requestContext.HttpContext.Request;
                siteCookie       = routeHttpRequest.Cookies["last_site"];
                parms            = new Dictionary <string, string>();
                host             = WebRequestHelper.GetHostNameFromRequest(HttpContext.Current);

                if (requestContext.RouteData.Values["PageId"] != null)
                {
                    // Pages using the default routing URL will have the page id in the RouteData.Values collection
                    pageId      = ( string )requestContext.RouteData.Values["PageId"];
                    isSiteMatch = true;
                }
                else if (requestContext.RouteData.DataTokens["PageRoutes"] != null)
                {
                    SiteCache site = GetSite(routeHttpRequest, host, siteCookie);
                    // Pages that use a custom URL route will have the page id in the RouteData.DataTokens collection
                    GetPageIdFromDataTokens(requestContext, site, out pageId, out routeId, out isSiteMatch);

                    foreach (var routeParm in requestContext.RouteData.Values)
                    {
                        parms.Add(routeParm.Key, ( string )routeParm.Value);
                    }
                }
                else if (((System.Web.Routing.Route)requestContext.RouteData.Route).Url.IsNullOrWhiteSpace())
                {
                    // if we don't have routing info then set the page ID to the default page for the site.

                    // Get the site, if not found use the default site
                    SiteCache site = GetSite(routeHttpRequest, host, siteCookie);
                    if (site == null)
                    {
                        site = SiteCache.Get(SystemGuid.Site.SITE_ROCK_INTERNAL.AsGuid());
                    }

                    if (site.DefaultPageId.HasValue)
                    {
                        pageId      = site.DefaultPageId.Value.ToString();
                        isSiteMatch = true;
                    }
                    else
                    {
                        throw new SystemException("Invalid Site Configuration");
                    }
                }

                // If the the page ID and site has not yet been matched
                if (string.IsNullOrEmpty(pageId) || !isSiteMatch)
                {
                    SiteCache site = GetSite(routeHttpRequest, host, siteCookie);

                    // if not found use the default site
                    if (site == null)
                    {
                        site = SiteCache.Get(SystemGuid.Site.SITE_ROCK_INTERNAL.AsGuid());
                    }

                    if (site != null)
                    {
                        // Check to see if this is a short link route
                        string shortlink = null;
                        if (requestContext.RouteData.Values.ContainsKey("shortlink"))
                        {
                            shortlink = requestContext.RouteData.Values["shortlink"].ToString();
                        }

                        // If shortlink have the same name as route and route's site did not match, then check if shortlink site match.
                        if (shortlink.IsNullOrWhiteSpace() && requestContext.RouteData.DataTokens["RouteName"] != null)
                        {
                            shortlink = requestContext.RouteData.DataTokens["RouteName"].ToString();
                        }

                        if (shortlink.IsNotNullOrWhiteSpace())
                        {
                            using (var rockContext = new Rock.Data.RockContext())
                            {
                                var pageShortLink = new PageShortLinkService(rockContext).GetByToken(shortlink, site.Id);

                                if (pageShortLink != null && (pageShortLink.SiteId == site.Id || requestContext.RouteData.DataTokens["RouteName"] == null))
                                {
                                    pageId  = string.Empty;
                                    routeId = 0;

                                    string trimmedUrl = pageShortLink.Url.RemoveCrLf().Trim();

                                    var transaction = new ShortLinkTransaction();
                                    transaction.PageShortLinkId = pageShortLink.Id;
                                    transaction.Token           = pageShortLink.Token;
                                    transaction.Url             = trimmedUrl;
                                    if (requestContext.HttpContext.User != null)
                                    {
                                        transaction.UserName = requestContext.HttpContext.User.Identity.Name;
                                    }

                                    transaction.DateViewed = RockDateTime.Now;
                                    transaction.IPAddress  = WebRequestHelper.GetClientIpAddress(routeHttpRequest);
                                    transaction.UserAgent  = routeHttpRequest.UserAgent ?? string.Empty;
                                    RockQueue.TransactionQueue.Enqueue(transaction);

                                    requestContext.HttpContext.Response.Redirect(trimmedUrl);
                                    return(null);
                                }
                            }
                        }

                        // If site has has been enabled for mobile redirect, then we'll need to check what type of device is being used
                        if (site.EnableMobileRedirect)
                        {
                            // get the device type
                            string u = routeHttpRequest.UserAgent;

                            var clientType = InteractionDeviceType.GetClientType(u);

                            bool redirect = false;

                            // first check if device is a mobile device
                            if (clientType == "Mobile")
                            {
                                redirect = true;
                            }

                            // if not, mobile device and tables should be redirected also, check if device is a tablet
                            if (!redirect && site.RedirectTablets && clientType == "Tablet")
                            {
                                redirect = true;
                            }

                            if (redirect)
                            {
                                if (site.MobilePageId.HasValue)
                                {
                                    pageId  = site.MobilePageId.Value.ToString();
                                    routeId = 0;
                                }
                                else if (!string.IsNullOrWhiteSpace(site.ExternalUrl))
                                {
                                    requestContext.HttpContext.Response.Redirect(site.ExternalUrl);
                                    return(null);
                                }
                            }
                        }
                    }
                }

                PageCache page = null;
                if (!string.IsNullOrEmpty(pageId))
                {
                    int pageIdNumber = 0;
                    if (int.TryParse(pageId, out pageIdNumber))
                    {
                        page = PageCache.Get(pageIdNumber);
                    }
                }

                if (page == null)
                {
                    // try to get site's 404 page
                    SiteCache site = GetSite(routeHttpRequest, host, siteCookie);
                    if (site != null && site.PageNotFoundPageId != null)
                    {
                        if (Convert.ToBoolean(GlobalAttributesCache.Get().GetValue("Log404AsException")))
                        {
                            Rock.Model.ExceptionLogService.LogException(
                                new Exception($"404 Error: {routeHttpRequest.Url.AbsoluteUri}"),
                                requestContext.HttpContext.ApplicationInstance.Context);
                        }

                        page = PageCache.Get(site.PageNotFoundPageId ?? 0);
                        requestContext.HttpContext.Response.StatusCode             = 404;
                        requestContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                    }
                    else
                    {
                        // no 404 page found for the site, return the default 404 error page
                        return((System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Http404Error.aspx", typeof(System.Web.UI.Page)));
                    }
                }

                CreateOrUpdateSiteCookie(siteCookie, requestContext, page);

                string theme      = page.Layout.Site.Theme;
                string layout     = page.Layout.FileName;
                string layoutPath = PageCache.FormatPath(theme, layout);

                try
                {
                    return(CreateRockPage(page, layoutPath, routeId, parms, routeHttpRequest));
                }
                catch (System.Web.HttpException)
                {
                    // The Selected theme and/or layout didn't exist so try to use the layout in the default theme.
                    theme = "Rock";

                    // Verify that Layout exists in the default theme directory and if not try use the default layout of the default theme
                    string layoutPagePath = string.Format("~/Themes/Rock/Layouts/{0}.aspx", layout);
                    if (!File.Exists(requestContext.HttpContext.Server.MapPath(layoutPagePath)))
                    {
                        layout = "FullWidth";
                    }

                    layoutPath = PageCache.FormatPath(theme, layout);

                    return(CreateRockPage(page, layoutPath, routeId, parms, routeHttpRequest));
                }
            }
            catch (Exception ex)
            {
                if (requestContext.HttpContext != null)
                {
                    requestContext.HttpContext.Cache["RockExceptionOrder"] = "66";
                    requestContext.HttpContext.Cache["RockLastException"]  = ex;
                }

                return((System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Error.aspx", typeof(System.Web.UI.Page)));
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Determine the logical page being requested by evaluating the routedata, or querystring and
        /// then loading the appropriate layout (ASPX) page
        /// </summary>
        /// <param name="requestContext"></param>
        /// <returns></returns>
        System.Web.IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }

            try
            {
                var httpRequest = requestContext.HttpContext.Request;

                var siteCookie = httpRequest.Cookies["last_site"];

                string pageId  = "";
                int    routeId = 0;

                var parms = new Dictionary <string, string>();

                // Pages using the default routing URL will have the page id in the RouteData.Values collection
                if (requestContext.RouteData.Values["PageId"] != null)
                {
                    pageId = (string)requestContext.RouteData.Values["PageId"];
                }

                // Pages that use a custom URL route will have the page id in the RouteDate.DataTokens collection
                else if (requestContext.RouteData.DataTokens["PageRoutes"] != null)
                {
                    var pageAndRouteIds = requestContext.RouteData.DataTokens["PageRoutes"] as List <PageAndRouteId>;
                    if (pageAndRouteIds != null && pageAndRouteIds.Count > 0)
                    {
                        // Default to first site/page
                        if (pageAndRouteIds.Count >= 1)
                        {
                            var pageAndRouteId = pageAndRouteIds.First();
                            pageId  = pageAndRouteId.PageId.ToJson();
                            routeId = pageAndRouteId.RouteId;
                        }

                        // Then check to see if any can be matched by site
                        if (pageAndRouteIds.Count > 1)
                        {
                            SiteCache site = null;

                            // First check to see if site was specified in querystring
                            int?siteId = httpRequest.QueryString["SiteId"].AsIntegerOrNull();
                            if (siteId.HasValue)
                            {
                                site = SiteCache.Read(siteId.Value);
                            }

                            // Then check to see if site can be determined by domain
                            if (site == null)
                            {
                                site = SiteCache.GetSiteByDomain(httpRequest.Url.Host);
                            }

                            // Then check the last site
                            if (site == null)
                            {
                                if (siteCookie != null && siteCookie.Value != null)
                                {
                                    site = SiteCache.Read(siteCookie.Value.AsInteger());
                                }
                            }

                            if (site != null)
                            {
                                foreach (var pageAndRouteId in pageAndRouteIds)
                                {
                                    var pageCache = PageCache.Read(pageAndRouteId.PageId);
                                    if (pageCache != null && pageCache.Layout != null && pageCache.Layout.SiteId == site.Id)
                                    {
                                        pageId  = pageAndRouteId.PageId.ToJson();
                                        routeId = pageAndRouteId.RouteId;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    foreach (var routeParm in requestContext.RouteData.Values)
                    {
                        parms.Add(routeParm.Key, (string)routeParm.Value);
                    }
                }

                // If page has not been specified get the site by the domain and use the site's default page
                if (string.IsNullOrEmpty(pageId))
                {
                    SiteCache site = SiteCache.GetSiteByDomain(httpRequest.Url.Host);
                    if (site == null)
                    {
                        // Use last site
                        if (siteCookie != null && siteCookie.Value != null)
                        {
                            site = SiteCache.Read(siteCookie.Value.AsInteger());
                        }
                    }

                    // if not found use the default site
                    if (site == null)
                    {
                        site = SiteCache.Read(SystemGuid.Site.SITE_ROCK_INTERNAL.AsGuid());
                    }

                    if (site != null)
                    {
                        // Check to see if this is a short link route
                        if (requestContext.RouteData.Values.ContainsKey("shortlink"))
                        {
                            string shortlink = requestContext.RouteData.Values["shortlink"].ToString();
                            using (var rockContext = new Rock.Data.RockContext())
                            {
                                var pageShortLink = new PageShortLinkService(rockContext).GetByToken(shortlink, site.Id);
                                if (pageShortLink != null)
                                {
                                    string trimmedUrl = pageShortLink.Url.RemoveCrLf().Trim();

                                    var transaction = new ShortLinkTransaction();
                                    transaction.PageShortLinkId = pageShortLink.Id;
                                    transaction.Token           = pageShortLink.Token;
                                    transaction.Url             = trimmedUrl;
                                    if (requestContext.HttpContext.User != null)
                                    {
                                        transaction.UserName = requestContext.HttpContext.User.Identity.Name;
                                    }
                                    transaction.DateViewed = RockDateTime.Now;
                                    transaction.IPAddress  = UI.RockPage.GetClientIpAddress(httpRequest);
                                    transaction.UserAgent  = httpRequest.UserAgent ?? "";
                                    RockQueue.TransactionQueue.Enqueue(transaction);

                                    requestContext.HttpContext.Response.Redirect(trimmedUrl);
                                    return(null);
                                }
                            }
                        }

                        // If site has has been enabled for mobile redirect, then we'll need to check what type of device is being used
                        if (site.EnableMobileRedirect)
                        {
                            // get the device type
                            string u = httpRequest.UserAgent;

                            var clientType = InteractionDeviceType.GetClientType(u);

                            bool redirect = false;

                            // first check if device is a mobile device
                            if (clientType == "Mobile")
                            {
                                redirect = true;
                            }

                            // if not, mobile device and tables should be redirected also, check if device is a tablet
                            if (!redirect && site.RedirectTablets)
                            {
                                if (clientType == "Tablet")
                                {
                                    redirect = true;
                                }
                            }

                            if (redirect)
                            {
                                if (site.MobilePageId.HasValue)
                                {
                                    pageId = site.MobilePageId.Value.ToString();
                                }
                                else if (!string.IsNullOrWhiteSpace(site.ExternalUrl))
                                {
                                    requestContext.HttpContext.Response.Redirect(site.ExternalUrl);
                                    return(null);
                                }
                            }
                        }

                        if (string.IsNullOrWhiteSpace(pageId))
                        {
                            if (site.DefaultPageId.HasValue)
                            {
                                pageId = site.DefaultPageId.Value.ToString();
                            }

                            if (site.DefaultPageRouteId.HasValue)
                            {
                                routeId = site.DefaultPageRouteId.Value;
                            }
                        }
                    }

                    if (string.IsNullOrEmpty(pageId))
                    {
                        throw new SystemException("Invalid Site Configuration");
                    }
                }

                PageCache page = null;

                if (!string.IsNullOrEmpty(pageId))
                {
                    int pageIdNumber = 0;
                    if (Int32.TryParse(pageId, out pageIdNumber))
                    {
                        page = PageCache.Read(pageIdNumber);
                    }
                }

                if (page == null)
                {
                    // try to get site's 404 page
                    SiteCache site = SiteCache.GetSiteByDomain(httpRequest.Url.Host);
                    if (site == null)
                    {
                        // Use last site
                        if (siteCookie != null && siteCookie.Value != null)
                        {
                            site = SiteCache.Read(siteCookie.Value.AsInteger());
                        }
                    }

                    if (site != null && site.PageNotFoundPageId != null)
                    {
                        if (Convert.ToBoolean(GlobalAttributesCache.Read().GetValue("Log404AsException")))
                        {
                            Rock.Model.ExceptionLogService.LogException(
                                new Exception(string.Format("404 Error: {0}", httpRequest.Url.AbsoluteUri)),
                                requestContext.HttpContext.ApplicationInstance.Context);
                        }

                        page = PageCache.Read(site.PageNotFoundPageId ?? 0);
                    }
                    else
                    {
                        // no 404 page found for the site, return the default 404 error page
                        return((System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Http404Error.aspx", typeof(System.Web.UI.Page)));
                    }
                }

                string theme      = page.Layout.Site.Theme;
                string layout     = page.Layout.FileName;
                string layoutPath = PageCache.FormatPath(theme, layout);

                if (siteCookie == null)
                {
                    siteCookie = new System.Web.HttpCookie("last_site", page.Layout.SiteId.ToString());
                }
                else
                {
                    siteCookie.Value = page.Layout.SiteId.ToString();
                }
                requestContext.HttpContext.Response.SetCookie(siteCookie);

                try
                {
                    // Return the page for the selected theme and layout
                    Rock.Web.UI.RockPage cmsPage = (Rock.Web.UI.RockPage)BuildManager.CreateInstanceFromVirtualPath(layoutPath, typeof(Rock.Web.UI.RockPage));
                    cmsPage.SetPage(page);
                    cmsPage.PageReference = new PageReference(page.Id, routeId, parms, httpRequest.QueryString);
                    return(cmsPage);
                }
                catch (System.Web.HttpException)
                {
                    // The Selected theme and/or layout didn't exist, attempt first to use the layout in the default theme.
                    theme = "Rock";

                    // If not using the default layout, verify that Layout exists in the default theme directory
                    if (layout != "FullWidth" &&
                        !File.Exists(requestContext.HttpContext.Server.MapPath(string.Format("~/Themes/Rock/Layouts/{0}.aspx", layout))))
                    {
                        // If selected layout doesn't exist in the default theme, switch to the Default layout
                        layout = "FullWidth";
                    }

                    // Build the path to the aspx file to
                    layoutPath = PageCache.FormatPath(theme, layout);

                    // Return the default layout and/or theme
                    Rock.Web.UI.RockPage cmsPage = (Rock.Web.UI.RockPage)BuildManager.CreateInstanceFromVirtualPath(layoutPath, typeof(Rock.Web.UI.RockPage));
                    cmsPage.SetPage(page);
                    cmsPage.PageReference = new PageReference(page.Id, routeId, parms, httpRequest.QueryString);
                    return(cmsPage);
                }
            }
            catch (Exception ex)
            {
                if (requestContext.HttpContext != null)
                {
                    requestContext.HttpContext.Cache["RockExceptionOrder"] = "66";
                    requestContext.HttpContext.Cache["RockLastException"]  = ex;
                }

                System.Web.UI.Page errorPage = (System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Error.aspx", typeof(System.Web.UI.Page));
                return(errorPage);
            }
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            var service = new PageShortLinkService(rockContext);

            // Get the merge fields
            var mergeFields = GetMergeFields(action);

            // Get the site
            int       siteId = GetAttributeValue(action, "Site", true).AsInteger();
            SiteCache site   = SiteCache.Get(siteId);

            if (site == null)
            {
                errorMessages.Add(string.Format("Invalid Site Value"));
                return(false);
            }

            // Get the token
            string token = GetAttributeValue(action, "Token", true).ResolveMergeFields(mergeFields);

            if (token.IsNullOrWhiteSpace())
            {
                int tokenLen = GetAttributeValue(action, "RandomTokenLength").AsIntegerOrNull() ?? 7;
                token = service.GetUniqueToken(site.Id, tokenLen);
            }

            // Get the target url
            string url = GetAttributeValue(action, "Url", true).ResolveMergeFields(mergeFields).RemoveCrLf().Trim();

            if (url.IsNullOrWhiteSpace())
            {
                errorMessages.Add("A valid Target Url was not specified.");
                return(false);
            }

            // Save the short link
            var link = service.GetByToken(token, site.Id);

            if (link != null)
            {
                if (!GetAttributeValue(action, "Overwrite").AsBoolean())
                {
                    errorMessages.Add(string.Format("The selected token ('{0}') already exists. Please specify a unique token, or configure action to allow token re-use.", token));
                    return(false);
                }
                else
                {
                    link.Url = url;
                }
            }
            else
            {
                link        = new PageShortLink();
                link.SiteId = site.Id;
                link.Token  = token;
                link.Url    = url;
                service.Add(link);
            }
            rockContext.SaveChanges();

            // Save the resulting short link url
            var attribute = AttributeCache.Get(GetAttributeValue(action, "Attribute").AsGuid(), rockContext);

            if (attribute != null)
            {
                string shortLink = link.ShortLinkUrl;

                SetWorkflowAttributeValue(action, attribute.Guid, shortLink);
                action.AddLogEntry(string.Format("Set '{0}' attribute to '{1}'.", attribute.Name, shortLink));
            }

            return(true);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (Page.IsValid)
            {
                PageShortLink link = null;

                using (var rockContext = new RockContext())
                {
                    var service = new PageShortLinkService(rockContext);

                    var errors = new List <string>();

                    int?linkId = hfShortLinkId.Value.AsIntegerOrNull();
                    if (linkId.HasValue)
                    {
                        link = service.Get(linkId.Value);
                    }

                    if (link == null)
                    {
                        link = new PageShortLink();
                        service.Add(link);
                    }

                    int?   siteId = ddlSite.SelectedValueAsInt();
                    string token  = tbToken.Text.Trim();
                    string url    = tbUrl.Text.RemoveCrLf().Trim();

                    if (!siteId.HasValue)
                    {
                        errors.Add("Please select a valid site.");
                    }

                    int minTokenLength = GetAttributeValue("MinimumTokenLength").AsIntegerOrNull() ?? 7;
                    if (token.IsNullOrWhiteSpace() || token.Length < minTokenLength)
                    {
                        errors.Add(string.Format("Please enter a token that is a least {0} characters long.", minTokenLength));
                    }
                    else if (siteId.HasValue && !service.VerifyUniqueToken(siteId.Value, link.Id, tbToken.Text))
                    {
                        errors.Add("The selected token is already being used. Please enter a different token.");
                    }

                    if (url.IsNullOrWhiteSpace())
                    {
                        errors.Add("Please enter a valid URL.");
                    }

                    if (errors.Any())
                    {
                        nbError.Text    = "Please correct the following:<ul><li>" + errors.AsDelimited("</li><li>") + "</li></ul>";
                        nbError.Visible = true;
                        return;
                    }

                    link.SiteId = siteId.Value;
                    link.Token  = token;
                    link.Url    = url;

                    if (!link.IsValid)
                    {
                        return;
                    }

                    rockContext.SaveChanges();
                }

                Dictionary <string, string> qryParams = new Dictionary <string, string>();
                qryParams["ShortLinkId"] = link.Id.ToString();
                NavigateToPage(RockPage.Guid, qryParams);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Handles the Click event of the btnEdit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnEdit_Click(object sender, EventArgs e)
        {
            var shortLink = new PageShortLinkService(new RockContext()).Get(int.Parse(hfShortLinkId.Value));

            ShowEditDetails(shortLink);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Determine the logical page being requested by evaluating the routedata, or querystring and
        /// then loading the appropriate layout (ASPX) page
        ///
        /// Pick url on the following priority order:
        /// 1. PageId
        /// 2. Route match and site match
        /// 3. ShortLink match and site match
        /// 4. Route and no site match
        /// 5. ShortLink with no site match
        /// 6. If there is no routing info in the request then set to default page
        /// 7. 404 if route does not exist
        ///
        /// </summary>
        /// <param name="requestContext"></param>
        /// <returns></returns>
        System.Web.IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            string pageId      = string.Empty;
            int    routeId     = 0;
            bool   isSiteMatch = false;
            Dictionary <string, string> parms;
            string          host;
            HttpRequestBase routeHttpRequest;
            HttpCookie      siteCookie;
            SiteCache       site;

            // Context cannot be null
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }

            try
            {
                routeHttpRequest = requestContext.HttpContext.Request;
                siteCookie       = routeHttpRequest.Cookies["last_site"];
                parms            = new Dictionary <string, string>();
                host             = WebRequestHelper.GetHostNameFromRequest(HttpContext.Current);
                site             = GetSite(host, siteCookie);

                if (requestContext.RouteData.Values["PageId"] != null)
                {
                    // Pages using the default routing URL will have the page id in the RouteData.Values collection
                    pageId = ( string )requestContext.RouteData.Values["PageId"];

                    // Does the page ID exist on the requesting site
                    isSiteMatch = IsSiteMatch(site, pageId.AsIntegerOrNull());

                    if (site != null && site.EnableExclusiveRoutes && !isSiteMatch)
                    {
                        // If the site has to match and does not then don't use the page ID. Set it to empty so the 404 can be returned.
                        pageId = string.Empty;
                    }
                    else if (!isSiteMatch)
                    {
                        // This page belongs to another site, make sure it is allowed to be loaded.
                        if (IsPageExclusiveToAnotherSite(site, pageId.AsIntegerOrNull(), null))
                        {
                            // If the page has to match the site and does not then don't use the page ID. Set it to empty so the 404 can be returned.
                            pageId = string.Empty;
                        }
                    }
                }
                else if (requestContext.RouteData.DataTokens["PageRoutes"] != null)
                {
                    // Pages that use a custom URL route will have the page id in the RouteData.DataTokens collection
                    GetPageIdFromDataTokens(requestContext, site, out pageId, out routeId, out isSiteMatch);

                    foreach (var routeParm in requestContext.RouteData.Values)
                    {
                        parms.Add(routeParm.Key, ( string )routeParm.Value);
                    }
                }
                else if (((System.Web.Routing.Route)requestContext.RouteData.Route).Url.IsNullOrWhiteSpace())
                {
                    // if we don't have routing info then set the page ID to the default page for the site.

                    // Get the site, if not found use the default site
                    if (site == null)
                    {
                        site = SiteCache.Get(SystemGuid.Site.SITE_ROCK_INTERNAL.AsGuid());
                    }

                    if (site.DefaultPageId.HasValue)
                    {
                        pageId      = site.DefaultPageId.Value.ToString();
                        isSiteMatch = true;
                    }
                    else
                    {
                        throw new SystemException("Invalid Site Configuration");
                    }
                }

                // If the the page ID and site has not yet been matched
                if (string.IsNullOrEmpty(pageId) || !isSiteMatch)
                {
                    // if not found use the default site
                    if (site == null)
                    {
                        site = SiteCache.Get(SystemGuid.Site.SITE_ROCK_INTERNAL.AsGuid());
                    }

                    // Are shortlinks enabled for this site? If so, check for a matching shortlink route.
                    if (site != null)
                    {
                        if (site.EnabledForShortening)
                        {
                            // Check to see if this is a short link route
                            string shortlink = null;
                            if (requestContext.RouteData.Values.ContainsKey("shortlink"))
                            {
                                shortlink = requestContext.RouteData.Values["shortlink"].ToString();
                            }
                            else
                            {
                                // Because we implemented shortlinks using a {shortlink} (catchall) route, it's
                                // possible the organization added a custom {catchall} route (at root level; no slashes)
                                // and it is overriding our shortlink route.  If they did, use it for a possible 'shortlink'
                                // route match.
                                if (requestContext.RouteData.DataTokens["RouteName"] != null && requestContext.RouteData.DataTokens["RouteName"].ToStringSafe().StartsWith("{"))
                                {
                                    var routeName = requestContext.RouteData.DataTokens["RouteName"].ToStringSafe().Trim(new Char[] { '{', '}' });
                                    shortlink = requestContext.RouteData.Values[routeName].ToStringSafe();
                                }
                            }

                            if (shortlink.IsNullOrWhiteSpace() && requestContext.RouteData.DataTokens["RouteName"] != null)
                            {
                                shortlink = requestContext.RouteData.DataTokens["RouteName"].ToString();
                            }

                            if (shortlink.IsNotNullOrWhiteSpace())
                            {
                                using (var rockContext = new Rock.Data.RockContext())
                                {
                                    var pageShortLink = new PageShortLinkService(rockContext).GetByToken(shortlink, site.Id);

                                    // Use the short link if the site IDs match or the current site and shortlink site are not exclusive.
                                    // Note: this is only a restriction based on the site chosen as the owner of the shortlink, the acutal URL can go anywhere.
                                    if (pageShortLink != null && (pageShortLink.SiteId == site.Id || (!site.EnableExclusiveRoutes && !pageShortLink.Site.EnableExclusiveRoutes)))
                                    {
                                        if (pageShortLink.SiteId == site.Id || requestContext.RouteData.DataTokens["RouteName"] == null)
                                        {
                                            pageId  = string.Empty;
                                            routeId = 0;

                                            string trimmedUrl = pageShortLink.Url.RemoveCrLf().Trim();

                                            var transaction = new ShortLinkTransaction
                                            {
                                                PageShortLinkId = pageShortLink.Id,
                                                Token           = pageShortLink.Token,
                                                Url             = trimmedUrl,
                                                DateViewed      = RockDateTime.Now,
                                                IPAddress       = WebRequestHelper.GetClientIpAddress(routeHttpRequest),
                                                UserAgent       = routeHttpRequest.UserAgent ?? string.Empty,
                                                UserName        = requestContext.HttpContext.User?.Identity.Name
                                            };

                                            RockQueue.TransactionQueue.Enqueue(transaction);

                                            requestContext.HttpContext.Response.Redirect(trimmedUrl, false);
                                            requestContext.HttpContext.ApplicationInstance.CompleteRequest();

                                            // Global.asax.cs will throw and log an exception if null is returned, so just return a new page.
                                            return(new System.Web.UI.Page());
                                        }
                                    }
                                }
                            }
                        }

                        // If site has has been enabled for mobile redirect, then we'll need to check what type of device is being used
                        if (site.EnableMobileRedirect)
                        {
                            // get the device type
                            string u = routeHttpRequest.UserAgent;

                            var clientType = InteractionDeviceType.GetClientType(u);

                            bool redirect = false;

                            // first check if device is a mobile device
                            if (clientType == "Mobile")
                            {
                                redirect = true;
                            }

                            // if not, mobile device and tables should be redirected also, check if device is a tablet
                            if (!redirect && site.RedirectTablets && clientType == "Tablet")
                            {
                                redirect = true;
                            }

                            if (redirect)
                            {
                                if (site.MobilePageId.HasValue)
                                {
                                    pageId  = site.MobilePageId.Value.ToString();
                                    routeId = 0;
                                }
                                else if (!string.IsNullOrWhiteSpace(site.ExternalUrl))
                                {
                                    requestContext.HttpContext.Response.Redirect(site.ExternalUrl, false);
                                    requestContext.HttpContext.ApplicationInstance.CompleteRequest();

                                    // Global.asax.cs will throw and log an exception if null is returned, so just return a new page.
                                    return(new System.Web.UI.Page());
                                }
                            }
                        }
                    }
                }

                PageCache page = null;
                if (!string.IsNullOrEmpty(pageId))
                {
                    int pageIdNumber = 0;
                    if (int.TryParse(pageId, out pageIdNumber))
                    {
                        page = PageCache.Get(pageIdNumber);
                    }
                }

                if (page == null)
                {
                    // try to get site's 404 page
                    if (site != null && site.PageNotFoundPageId != null)
                    {
                        if (Convert.ToBoolean(GlobalAttributesCache.Get().GetValue("Log404AsException")))
                        {
                            Rock.Model.ExceptionLogService.LogException(
                                new Exception($"404 Error: {routeHttpRequest.Url.AbsoluteUri}"),
                                requestContext.HttpContext.ApplicationInstance.Context);
                        }

                        page = PageCache.Get(site.PageNotFoundPageId ?? 0);
                        requestContext.HttpContext.Response.StatusCode             = 404;
                        requestContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                    }
                    else
                    {
                        // no 404 page found for the site, return the default 404 error page
                        return((System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Http404Error.aspx", typeof(System.Web.UI.Page)));
                    }
                }

                CreateOrUpdateSiteCookie(siteCookie, requestContext, page);

                string theme      = page.Layout.Site.Theme;
                string layout     = page.Layout.FileName;
                string layoutPath = PageCache.FormatPath(theme, layout);

                try
                {
                    return(CreateRockPage(page, layoutPath, routeId, parms, routeHttpRequest));
                }
                catch (System.Web.HttpException)
                {
                    // The Selected theme and/or layout didn't exist so try to use the layout in the default theme.
                    theme = "Rock";

                    // Verify that Layout exists in the default theme directory and if not try use the default layout of the default theme
                    string layoutPagePath = string.Format("~/Themes/Rock/Layouts/{0}.aspx", layout);
                    if (!File.Exists(requestContext.HttpContext.Server.MapPath(layoutPagePath)))
                    {
                        layout = "FullWidth";
                    }

                    layoutPath = PageCache.FormatPath(theme, layout);

                    return(CreateRockPage(page, layoutPath, routeId, parms, routeHttpRequest));
                }
            }
            catch (Exception ex)
            {
                if (requestContext.HttpContext != null)
                {
                    requestContext.HttpContext.Cache["RockExceptionOrder"] = "66";
                    requestContext.HttpContext.Cache["RockLastException"]  = ex;
                }

                return((System.Web.UI.Page)BuildManager.CreateInstanceFromVirtualPath("~/Error.aspx", typeof(System.Web.UI.Page)));
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Uses the DataTokens to contstruct a list of PageAndRouteIds
        /// If any exist then set page and route ID to the first one found.
        /// Then loop through the collection looking for a site match, if one is found then set the page and route ID to that
        /// and the IsSiteMatch property to true.
        /// </summary>
        private void GetPageIdFromDataTokens(RequestContext routeRequestContext, SiteCache site, out string pageId, out int routeId, out bool isSiteMatch)
        {
            pageId      = string.Empty;
            routeId     = 0;
            isSiteMatch = false;

            if (site == null)
            {
                return;
            }

            // Pages that use a custom URL route will have the page id in the RouteData.DataTokens collection, if there are not any then just return.
            var pageAndRouteIds = (List <PageAndRouteId>)routeRequestContext.RouteData.DataTokens["PageRoutes"];

            if (pageAndRouteIds == null || !pageAndRouteIds.Any())
            {
                return;
            }

            // First try to find a match for the site
            // See if this is a possible shortlink
            if (routeRequestContext.RouteData.DataTokens["RouteName"] != null && routeRequestContext.RouteData.DataTokens["RouteName"].ToStringSafe().StartsWith("{"))
            {
                // Get the route value
                string routeValue = routeRequestContext.RouteData.Values.Values.FirstOrDefault().ToStringSafe();

                // See if the route value string matches a shortlink for this site.
                var pageShortLink = new PageShortLinkService(new Rock.Data.RockContext()).GetByToken(routeValue, site.Id);
                if (pageShortLink != null && pageShortLink.SiteId == site.Id)
                {
                    // The route entered matches a shortlink for the site, so lets NOT set the page ID for a catch-all route and let the shortlink logic take over.
                    return;
                }
            }

            // Not a short link so cycle through the pages and routes to find a match for the site.
            foreach (var pageAndRouteId in pageAndRouteIds)
            {
                var pageCache = PageCache.Get(pageAndRouteId.PageId);
                if (pageCache != null && pageCache.Layout != null && pageCache.Layout.SiteId == site.Id)
                {
                    pageId      = pageAndRouteId.PageId.ToStringSafe();
                    routeId     = pageAndRouteId.RouteId;
                    isSiteMatch = true;
                    return;
                }
            }

            // Default to first site/page that is not Exclusive
            foreach (var pageAndRouteId in pageAndRouteIds)
            {
                if (!IsPageExclusiveToAnotherSite(site, pageAndRouteId.PageId, pageAndRouteId.RouteId))
                {
                    // These are safe to assign as defaults
                    pageId  = pageAndRouteId.PageId.ToStringSafe();
                    routeId = pageAndRouteId.RouteId;

                    return;
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Handles the OnSave event of the masterPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void masterPage_OnSave(object sender, EventArgs e)
        {
            Page.Validate(BlockValidationGroup);
            if (Page.IsValid)
            {
                PageShortLink link = null;

                using (var rockContext = new RockContext())
                {
                    var service = new PageShortLinkService(rockContext);

                    var errors = new List <string>();

                    int?   siteId = ddlSite.SelectedValueAsInt();
                    string token  = tbToken.Text.Trim();
                    string url    = tbUrl.Text.Trim();

                    if (!siteId.HasValue)
                    {
                        errors.Add("Please select a valid site.");
                    }

                    if (token.IsNullOrWhiteSpace() || token.Length < _minTokenLength)
                    {
                        errors.Add(string.Format("Please enter a token that is a least {0} characters long.", _minTokenLength));
                    }
                    else if (siteId.HasValue && !service.VerifyUniqueToken(siteId.Value, 0, tbToken.Text))
                    {
                        errors.Add("The selected token is already being used. Please enter a different token.");
                    }

                    if (url.IsNullOrWhiteSpace())
                    {
                        errors.Add("Please enter a valid URL.");
                    }

                    if (errors.Any())
                    {
                        nbError.Text    = "Please correct the following:<ul><li>" + errors.AsDelimited("</li><li>") + "</li></ul>";
                        nbError.Visible = true;
                        return;
                    }

                    link        = new PageShortLink();
                    link.SiteId = siteId.Value;
                    link.Token  = token;
                    link.Url    = url;

                    service.Add(link);
                    rockContext.SaveChanges();
                }

                if (link != null)
                {
                    using (var rockContext = new RockContext())
                    {
                        string script = "window.parent.Rock.controls.modal.close();";
                        ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "close-modal", script, true);
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Builds the dynamic routes.
        /// </summary>
        public void BuildDynamicRoutes()
        {
            var constraintResolver = _applicationBuilder.ApplicationServices.GetRequiredService <IInlineConstraintResolver>();
            var builder            = new RouteBuilder(_applicationBuilder);

            using (var rockContext = new RockContext())
            {
                var routes     = new PageRouteService(rockContext).Queryable().ToList();
                var shortlinks = new PageShortLinkService(rockContext).Queryable().ToList();

                //
                // 3. Add Routes with a site match.
                //
                foreach (var route in routes)
                {
                    var pageCache = PageCache.Get(route.PageId);

                    builder.Routes.Add(new Route(
                                           new RouteHandler(PageRouteAsync),
                                           null,
                                           route.Route,
                                           new RouteValueDictionary(new
                    {
                        route.PageId,
                        RouteId = route.Id
                    }),
                                           new RouteValueDictionary(new
                    {
                        Site = new SiteMatchConstraint(pageCache.Layout.SiteId)
                    }),
                                           new RouteValueDictionary(),
                                           constraintResolver));
                }

                //
                // 4. Add Shortlink match with a site match.
                //
                foreach (var shortlink in shortlinks)
                {
                    builder.Routes.Add(new Route(
                                           new RouteHandler(ShortLinkAsync),
                                           null,
                                           shortlink.Token,
                                           new RouteValueDictionary(new
                    {
                        ShortLinkId = shortlink.Id,
                        shortlink.Url,
                        shortlink.Token
                    }),
                                           new RouteValueDictionary(new { Site = new SiteMatchConstraint(shortlink.SiteId) }),
                                           new RouteValueDictionary(),
                                           constraintResolver));
                }

                //
                // 5. Add Routes with no site match.
                //
                foreach (var route in routes)
                {
                    var pageCache = PageCache.Get(route.PageId);

                    builder.Routes.Add(new Route(
                                           new RouteHandler(PageRouteAsync),
                                           null,
                                           route.Route,
                                           new RouteValueDictionary(new
                    {
                        route.PageId,
                        RouteId = route.Id
                    }),
                                           new RouteValueDictionary(),
                                           new RouteValueDictionary(),
                                           constraintResolver));
                }

                //
                // 4. Add Shortlink match with no site match.
                //
                foreach (var shortlink in shortlinks)
                {
                    builder.Routes.Add(new Route(
                                           new RouteHandler(ShortLinkAsync),
                                           null,
                                           shortlink.Token,
                                           new RouteValueDictionary(new
                    {
                        ShortLinkId = shortlink.Id,
                        shortlink.Url,
                        shortlink.Token
                    }),
                                           new RouteValueDictionary(),
                                           new RouteValueDictionary(),
                                           constraintResolver));
                }
            }

            _dynamicRouter = builder.Build();
        }