Handling Legacy Links in Xperience by Kentico Using Kentico Middleware

To handle legacy links from an old website in ‘Xperience by Kentico’, implement a custom middleware approach.

While Kentico offers the IWebPageRedirectManager API, using it for bulk historical paths can clutter your content database and degrade performance. Instead, executing redirects at the ASP.NET Core middleware level catches old URLs before they hit the Kentico routing engine, preserving server resources.

First, create a Redirect Dictionary or MapCreate a structured list mapping your old website URLs to your new ‘Xperience by Kentico’ page paths. You can store this in a redirects.json file in your project root.

redirects.json

{
  "/old-category/old-product-page.html": "/products/new-product-name",
  "/about-us.php": "/about-us",
  "/contact.asp": "/contact",
  "/TestRedirect": "/somepage"
}

Next, implement the Custom Middleware.
Create a new C# class named LegacyRedirectMiddleware.cs. Place it under your Resources folder.
This middleware intercepts incoming HTTP requests, checks if the path matches a legacy URL, and returns a Permanent 301 Redirect to preserve your SEO rankings.

LegacyRedirectMiddleware.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;
using System.IO;
using System.Text.Json;

public class LegacyRedirectMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly IFileProvider _fileProvider;
    private const string CacheKey = "RedirectMap";
    private const string FileName = "redirects.json";

    public LegacyRedirectMiddleware(RequestDelegate next, IMemoryCache cache, IWebHostEnvironment env)
    {
        _next = next;
        _cache = cache;
        // Point to the project root or a folder like 'Data'
        _fileProvider = new PhysicalFileProvider(env.ContentRootPath);
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var redirectMap = _cache.GetOrCreate(CacheKey, entry =>
        {
            // Set up a change token so the cache clears when the file is saved
            entry.AddExpirationToken(_fileProvider.Watch(FileName));

            var filePath = Path.Combine(_fileProvider.GetFileInfo(FileName).PhysicalPath!);

            if (File.Exists(filePath))
            {
                var jsonContent = File.ReadAllText(filePath);
                return JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent)
                       ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            }

            return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        });

        string requestPath = context.Request.Path.Value ?? string.Empty;

        if (redirectMap.TryGetValue(requestPath, out string newPath))
        {
            var queryString = context.Request.QueryString.Value ?? string.Empty;
            context.Response.Redirect($"{newPath}{queryString}", permanent: true);
            return;
        }

        await _next(context);
    }
}

Next, register the Middleware in Program.cs.
Open your application’s Program.cs file and register this middleware before the Kentico Routing configuration to intercept requests early (right before app.Run();).

// Legacy Redirect Middleware - Resources/LegacyRedirectMiddleware.cs //
app.UseMiddleware<LegacyRedirectMiddleware>();

// Your legacy redirect middleware before Routing and Kentico //
app.UseRouting();
app.Run();

Benefits of Handling Legacy Links Using Kentico Middleware

Handling legacy links via custom middleware rather than stuffing them into the CMS database comes down to three major wins: speed, database health, and architectural sanity.

Here is exactly why this approach is a better engineering choice for your Xperience by Kentico site.

1. Light-Speed Execution (Bypassing the CMS)
When a request comes into your server, it goes through the ASP.NET Core middleware pipeline before it ever touches the Kentico application layer or routing engine.

The Middleware Way: The request hits your custom middleware, matches a lightweight list (or a fast look-up file), and immediately sends a 301 Moved Permanently response back to the browser. The server stops processing right there.

The DB Way: If you use the native IWebPageRedirectManager, the request has to travel deep into the Kentico routing engine, spin up database connections, query the content tables, and then issue the redirect.

By catching old URLs early, you save precious CPU cycles and handle legacy traffic with almost zero overhead.

2. Keeping Your Database Clean
Every historical link you import into Kentico’s native redirect manager creates data overhead. If you are migrating an old site with hundreds or thousands of legacy URLs, your database will quickly balloon with “dead weight” data.

This clutter can slow down your regular content queries, make database backups larger, and complicate future migrations. Middleware allows you to keep this historical mapping entirely separate from your operational content.

3. Graceful Deprecation
Legacy links have a shelf life. Five years from now, you might want to strip out those old redirects once search engines have fully updated their indexes and users stop clicking old bookmarks.

If they are embedded in your CMS database, cleaning them up means running risky SQL delete scripts or manually deleting thousands of entries in a UI.

If they are in middleware, you can easily update a JSON mapping file or eventually delete a single file of code without ever touching your live production database.

The Golden Rule of Routing: If a URL is part of the current website’s structure, manage it in the CMS. If a URL is a ghost of websites past, kill it at the front door with middleware.