How to Redirect Your Old URL to New One with .NET Core

In this tutorial, you will learn how to deploy new .NET Core website to replace an existing ASP.NET based website. This new site has been optimized for performance, stability, and SEO value. As such, the URL structures for major sections of the website had changed. Many of page URL’s were not majorly concerning as the search engines would easily pick up the new URL’s in a matter of a few days. However, the old blog URL’s that were shared publicly on many external channels became a big concern. I’ll dive into how I solved this in a manner that works, quickly, easily and without major impacts to performance etc

In previous post, we also have explained about how to redirect user to a different page and also Asp.net core middleware. You can see many solutions about it. This is other solution that might be more interesting and easier that you can follow.

ASP.NET Core Routing to the Rescue

In each of our applications, we set up our routing for MVC to define our URL structures. Most of our conversations are about what our CURRENT application is doing, but it is important to remember that this pipeline is ALREADY executing on all requests. So if I can inject something here I’m limiting the amount of overhead I’m introducing, as well as the risk associated with making the change.

ASPHostPortal

The implementation

The implementation, using basic Routing to assist was simple and comprised of only two steps.

Step 1: The Route

The first step of the process was to define the route. I was working with the redirection of URL’s that started with the format of /Resources/Blog/Post/XX/ZZ. Where XX was an integer value and ZZ was a “SEO Friendly” url fragment. This provided a great setup and I was able to add the following route definition.

routes.MapRoute("oldBlog",
    "Resources/Blog/Post/{id}/{*fragment}",
    new {Controller = "Redirect", Action = "OldBlog"});

As you can see here I created a route called “oldBlog” that matches the format listed creating two parameters, id and fragment. I also define that it should send requests to the Redirect controller and the OldBlog action. I don’t really care about the fragment portion of the URL, but needed to be sure to capture it.

Step Two: Lookup the Redirects

Inside of my redirect controller the process of redirecting was quite simple. I wanted to find the new URL based on the old id. If a match was found I want a permanent redirect to the new URL. If no match is found I want a permanent redirect to the blog page. For this I needed two parts, the first was a dictionary for mapping.

private static readonly IDictionary<int, string> 
MappingDictionary = new Dictionary<int, string>()
        {
            {400, "NewURLHere" }
        };

In this case, I decided to use a private static dictionary due to the limited number of items. If this was a changing list, or if I had a large number of them I could easily adjust to use a different format. The key is that I identify the mapping from old to new here. If your mapping was other than an ID it is easy to adapt. The final piece is to then define the controller action that performs the redirect.

public IActionResult OldBlog(int id)
{
    if (MappingDictionary.TryGetValue(id, out string newPath)) 
        return RedirectPermanent(newPath);
    return RedirectPermanent("/insights/blog");
}

And this is all that we need. Lookup from the dictionary, if found, redirect to it. If not, redirect to my default destination.

The Result

After implementing this solution, I was able to map all postings and properly manage the redirects. In addition, it was possible to do this without adding any additional pipeline overhead than the standard ASP.NET Core routing processes, leveraging all of their performance optimizations. I hope this helps you with your projects.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *