Example #1
0
        /// <summary>
        /// Returns the calculated destination URL for the specified <paramref name="redirect"/>.
        /// </summary>
        /// <param name="redirect">The redirect.</param>
        /// <param name="uri">The inbound URL.</param>
        /// <returns>The destination URL.</returns>
        public virtual string GetDestinationUrl(IRedirectBase redirect, Uri uri)
        {
            if (string.IsNullOrWhiteSpace(redirect?.Destination?.Url))
            {
                return(null);
            }

            // Get the query string (if any)
            string query = redirect.Destination.Query;

            // Get the fragment (if any)
            string fragment = redirect.Destination.Fragment;

            // Merge the existing query string with the query string of "uri" (eg. from the inbound request)
            if (uri != null && uri.Query.HasValue() && redirect.ForwardQueryString)
            {
                query = MergeQueryString(query, uri.Query);
            }

            // For content and media, we need to look up the most recent URL
            IPublishedContent content = null;

            switch (redirect.Destination.Type)
            {
            case RedirectDestinationType.Content:
                if (_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext context))
                {
                    content = context.Content.GetById(redirect.Destination.Key);
                }
                break;

            case RedirectDestinationType.Media:
                if (_umbracoContextAccessor.TryGetUmbracoContext(out context))
                {
                    content = context.Media.GetById(redirect.Destination.Key);
                }
                break;
            }

            // Put the destination URL back together
            return(RedirectsUtils.ConcatUrl(content?.Url() ?? redirect.Destination.Url, query, fragment));
        }
Example #2
0
        protected override void Migrate()
        {
            try {
                // Get the DTOs for all redirects in the database
                List <RedirectDto> dtos = Database.Fetch <RedirectDto>("SELECT * FROM [SkybrudRedirects];");

                // Map the path to a special redirects folder
                string dir = _hostingEnvironment.MapPathWebRoot("~/App_Data/Skybrud.Umbraco.Redirects");
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                // Map the path to the JSON file and save the DTOs to disk as a backup
                string path = Path.Combine(dir, $"Redirects_Backup_{DateTime.UtcNow:yyyyMMddHHmmss}.json");
                JsonUtils.SaveJsonArray(path, JArray.FromObject(dtos));

                // Add the "DestinationQuery" column to the database table
                if (!ColumnExists(RedirectDto.TableName, nameof(RedirectDto.DestinationQuery)))
                {
                    Create
                    .Column(nameof(RedirectDto.DestinationQuery))
                    .OnTable(RedirectDto.TableName)
                    .AsString()
                    .WithDefaultValue(string.Empty)
                    .Do();
                }

                // Add the "DestinationFragment" column to the database table
                if (!ColumnExists(RedirectDto.TableName, nameof(RedirectDto.DestinationFragment)))
                {
                    Create
                    .Column(nameof(RedirectDto.DestinationFragment))
                    .OnTable(RedirectDto.TableName)
                    .AsString()
                    .WithDefaultValue(string.Empty)
                    .Do();
                }

                // Wrap the DTOs as RedirectItem instances
                List <Redirect> redirects = dtos
                                            .Select(x => new Redirect(x))
                                            .ToList();

                foreach (Redirect redirect in redirects)
                {
                    // Skip the redirect if we didn't detect any changes
                    if (!RedirectsUtils.NormalizeUrlParts(redirect))
                    {
                        Logger.LogInformation("Redirect with key {Key} is already up-to-date.", redirect.Key);
                        continue;
                    }

                    // Update the redirect in the database
                    Database.Execute(
                        "UPDATE [SkybrudRedirects] SET [DestinationUrl] = @0, [DestinationQuery] = @1, [DestinationFragment] = @2 WHERE [Key] = @3;",
                        redirect.Destination.Url, redirect.Destination.Query, redirect.Destination.Fragment, redirect.Key
                        );

                    Logger.LogInformation("Updated redirect with key {Key}.", redirect.Key);
                }
            } catch (Exception ex) {
                throw new Exception("Failed migration for Skybrud.Umbraco.Redirects. See the Umbraco log for more information.", ex);
            }
        }