Kentico Cloud Page Redirects with ASP.NET Core

Image showing redirection
by Brad Jolicoeur
02/03/2019

Page redirects are an important component of any enterprise CMS large or small. As a developer, you will want to empower the content editors with the ability to manage the list of page redirects. As the owners of the content, they are in the best position to know when a link is broken or will become broken. 

This article shows how to implement page redirects in your ASP.NET Core application using Kentico Cloud as the repository for the list of redirects.

Important Note:  If you use a 301 permanent redirect, chrome will cache the redirect indefinitely. If you are experimenting with permanent redirects, make sure you use incognito mode so that the redirects are not permanently cached. Another alternative is to use 302 temporary redirects until you are comfortable with what you have implemented.  

Reasons for redirects

There are two primary reasons for page level redirects in a website.

Avoiding broken links:  Site redesign usually means URL paths change causing broken links from sites that refer to your site or embedded links in existing content.  Broken links will create a bad user experience, but will also have a negative impact on Search Engine Optimization (SEO).  In this case a 301 permanent redirect is the best option since it will indicate to the search engines that there is a replacement page.

Creating shortcut paths for marketing campaigns: For example if you want to promote something on your site via a podcast, you can create a simple path that is easy to verbally communicate and redirects to users to a landing page somewhere on your site. For example, yourdomain.com/openmic is easier to say and remember vs yourdomain.com/events/detail/someopenmicevent123.  In this case, a 302 redirect might be appropriate since you may want to change the landing page you are targeting.

Steps To Implement

To implement page redirects using ASP.NET Core and Kentico Cloud you will need to complete 4 simple steps to implement middleware to execute the redirects. 

  1. Create redirect content types in Kentico Cloud
  2. Implement a c# class for your new content type 
  3. Implement middleware class 
  4. Wire up the middleware in your startup.cs

The details for each of these steps are below and you can see a full working example in my GitHub repository.

GitHub Example Site: https://github.com/bradjolicoeur/bradjolicoeur

Detailed Steps

First you will need to create a content item in Kentico Cloud that will store the path you need to redirect and the destination path. You could also add a permanent redirect toggle if you need it. Just make sure you consider that the browser caches permanent redirects indefinitely.

Kentico Cloud content type created for page redirects


Once you have the content type defined in Kentico Cloud, you will need to create a content type class to match. I use the Cloud Generator utility to generate my content type models in c#. 

Model Generator: https://github.com/Kentico/cloud-generators-net

public partial class UrlRedirect
{
       public const string Codename = "url_redirect";
       public const string RedirectToCodename = "redirect_to";
       public const string RedirectFromCodename = "redirect_from";

       public string RedirectTo { get; set; }
       public string RedirectFrom { get; set; }
       public ContentItemSystemAttributes System { get; set; }
}


Now that you have a source for your redirect paths, you can implement the redirect middleware.

Full middleware class example here: GitHub: RedirectMiddleware.cs

The middleware will perform the actual redirect in the ASP.NET pipeline and will be initialized in startup.cs in a later step. We will inject the IDeliveryClient into this middleware class so we can pull the list of redirects from Kentico Cloud. 

 private RequestDelegate NextDelegate { get; set; }
 private IServiceProvider ServiceProvider { get; set; }
 private IDeliveryClient DeliveryClient { get; set; }

public RedirectMiddleware(RequestDelegate nextDelegate, 
            IServiceProvider serviceProvider, IDeliveryClient deliveryClient)
{
            NextDelegate = nextDelegate;
            ServiceProvider = serviceProvider;
            DeliveryClient = deliveryClient;
 }

To pull the list of redirects from the delivery client, I created a private method within the middeware class that executes a query against Kentico Cloud to pull the full list of redirects. I'm expecting this to be cached based on my implementation of IDeliveryClient, so I pull the whole list instead of just pulling the specific redirect. If your list of redirects become extensive you may want to be more specific with your query.

private async Task<IEnumerable<UrlRedirect>> GetRedirects()
{
           var response = await DeliveryClient.GetItemsAsync<UrlRedirect>(
              new EqualsFilter("system.type", UrlRedirect.Codename)
             ).ConfigureAwait(false);

           return response.Items;
}


To perform the actual redirect, the middleware class requires an Invoke method that will be executed by the pipeline. Note that the list of redirects could be sourced from anywhere like a database, text file, etc. Using Kentico Cloud means your content editors are empowered to manage the redirects.

public async Task Invoke(HttpContext httpContext)
{
     //The path from the request
     string requestURL = httpContext.Request.Path.ToString().ToLower();

     //pull the full list of redirects 
     var redirects = await GetRedirects();

     //search the full list for a redirect that matches the request path
     var redirect = redirects.Where(q => q.RedirectFrom
                    .Equals(requestURL, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        
      if (redirect != null)
      {
            //a redirect was found in the list to be executed
            httpContext.Response.Redirect(redirect.RedirectTo.ToLower(), false);
      }
          else
     {
           //invoke the next delegate in the pipeline
           await NextDelegate.Invoke(httpContext).ConfigureAwait(false);
      }
}


The last step is to wire up your middleware in startup.cs.

//use the name of your middleware class
app.UseMiddleware<RedirectMiddleware>();

app.UseMvc();


You have now enabled the folks who maintain content in Kentico cloud to manage redirects on the site!

Additional Resources