Redirecting old urls to new in ASP.Net MVC



Recently I migrated my classic ASP website to ASP.Net MVC. However, there were many websites still linking to specific .asp pages that no longer exist. I looked for some help on Google so that I could easily redirect the legacy URLs to the new one.

Thanks to Mikesdonetting post that gave me that ‘real code’. You will need to read this post for clear understanding.

While the above post covers the most important aspect of redirecting (LegacyUrlRoute class), I have modified the code so that it suits a more common scenario.

Here is the code:

namespace www.Helpers
{
    class RedirectRule
    {
        public string OldUrlContains;
        public string OldUrlContainsNot;
        public string NewUrl;
 
        public RedirectRule(string strOldUrlContains, string strOldUrlContainsNot, string strNewUrl)
        {
            OldUrlContains = strOldUrlContains;
            OldUrlContainsNot = strOldUrlContainsNot;
            NewUrl = strNewUrl;
        }
    };
 
 
    public class LegacyUrlRoute : RouteBase
    {
        RedirectRule[] RedirectRules =
        {
            new RedirectRule("Notezilla/default.asp", "", "/Notezilla"),
            new RedirectRule("RecentX/default.asp", "", "/RecentX"),
        };
 
 
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            const string status = "301 Moved Permanently";
            var request = httpContext.Request;
            var response = httpContext.Response;
            var legacyUrl = request.Url.ToString();
            var newUrl = "";
 
            foreach (RedirectRule rule in RedirectRules)
            {
                //if we don't have to check for a string that does not exist in the url
                if (rule.OldUrlContainsNot.Length == 0)
                {
 
                    //this does a case insensitive comparison
                    if (legacyUrl.IndexOf(rule.OldUrlContains, 0, StringComparison.CurrentCultureIgnoreCase) >= 0)
                    {
                        newUrl = rule.NewUrl;
                    }
                }
                else
                {
                    //if we don't have to check for a string that does not exist in the url
                    if ((legacyUrl.IndexOf(rule.OldUrlContains, 0, StringComparison.CurrentCultureIgnoreCase) >= 0)
                        //so that it doesn't go in infinite loop since the end part of both urls are same
                        && (!(legacyUrl.IndexOf(rule.OldUrlContainsNot, 0, StringComparison.CurrentCultureIgnoreCase) >= 0)))
                    {
                        newUrl = rule.NewUrl;
                    }
                }
 
                //found anything?
                if (newUrl.Length > 0)
                {
                    break;
                }
 
            }
 
 
            if (newUrl.Length > 0)
            {
                response.Status = status;
                response.RedirectLocation = newUrl;
                response.End();
            }
 
            return null;
        }
 
        public override VirtualPathData GetVirtualPath(RequestContext requestContext,
                    RouteValueDictionary values)
        {
            return null;
        }
    }
 
 
}

Here is the explanation:

RedirectRule is a class that holds 1) the old url substring that we much check for, 2) the old url substring that should not exist in the url and 3) the new url which the user must be redirected to.

We initialize an array of such RedirectRule objects and check (inside the function GetRouteData) if the active url matches the criteria given in each rule. If it matches then we redirect to the new url.

Let us see, when we will have the case where RedirectRule.OldUrlContainsNot will need to be used.

Imagine that the old Url was ‘Notezilla/NotezillaSetup.exe’ and the new Url is ‘/Downloads/Notezilla/NotezillaSetup.exe’. In our case if we just check for the old Url then we will end up in infinite loop since the end part of both old and new Url is same (Notezilla/NotezillaSetup.exe). For this reason we need OldUrlContainsNot. In this case we will set OldUrlContainsNot to ‘/Downloads’ so that we do not get in to infinite loop.

Once you are done with the above code just add LegacyUrlRoute to existing routes in Global.asax.cs

 
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
    routes.Add(new LegacyUrlRoute());
}

That’s it.

Thanks.



2 thoughts on “Redirecting old urls to new in ASP.Net MVC”

  1. thanks for your post
    i use your code but i have a problem

    when i have old url = /controller1/action1
    and new url = /controller2/action2

    return url= /controller1/controller2/action2

    but i wanna new url = /controller2/action2

  2. Hello, I have a website with set of html files and now i am migrating to MVC application. I tried to use the same set of code for redirecting old URLs to new MVC but getting 404 error. Here is the RouteConfig.cs code and created a similar class like above code and set the redirection as mentioned.

    Sample code from LegacyUrlRoute
    new RedirectRule(“oldpage.html”, “”, “/department/letter/july”)

    Here department is my controller and letter is the action and july is the ID. If i directly give this /department/letter/july in URL it works. Can you please advice?

    public class RouteConfig
    {
    public static void RegisterRoutes(RouteCollection routes)
    {
    routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

    routes.Add(new LegacyUrlRoute());

    routes.MapRoute(
    name: “Default”,
    url: “{controller}/{action}/{id}”,
    defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
    );

    }
    }

Leave a Reply

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