Search code examples
asp.net-mvcasp.net-mvc-routing

ASP.NET MVC Redirect Old URL to New URL


I have a website with set of html files and now i am migrating to MVC application. I tried to use the code mentioned in the blog

http://www.bloggersworld.com/index.php/redirecting-old-urls-to-new-in-aspnet-mvc/

for redirecting old URLs to new MVC but getting 404 error.

Here is the RouteConfig.cs code

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 }
        );
    }
}

I created a similar class like mentioned in the blog 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.

I noticed the issue is with .html in URL and not with .aspx.

If i give URL as localhost/oldpage.aspx then it works correctly but if i give localhost/oldpage.html it goes to 404

Can you please advice?


Solution

  • HTML Handler has to be added in web.config which would resolve the issue related to redirecting HTML URLs.

    Here is the code snippet which is almost same as the link given in the question.

    RouteConfig.cs

    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 }
          );
    
        }
    }
    

    LegacyUrlRoute class:

          public 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("oldhtmlurlvalue", "", "/controller/action"),
            };
    
    
            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;
            }
        }
    

    Web.Config

    <system.webServer>
       <handlers>
          <add name="HtmlScriptHandler" path="*.html" verb="*"
             preCondition="integratedMode" type="System.Web.StaticFileHandler" />
        </handlers>
      </system.webServer>
    

    If the above config handler is not written then when we type https://localhost/sample/page.html then the browser throws 404 error.