Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permanent Redirect Legacy Routes for static files in ASP.Net MVC

Our old ASP.net site stored static images in a sub directory on the root called /images.

Our new ASP.net MVC site stores these images in the new layout of /Content/Images

I've changed all the pages in the site to cope with the new folder structure, but I'd like to set up Permanent Redirects from the old static images to the new location.

Our site is hosted, and I don't have control over IIS, so what is the best approach to solve this?

like image 620
Scott Ferguson Avatar asked Jan 12 '11 02:01

Scott Ferguson


1 Answers

I use the following code for my MVC 2 websites:

// The legacy route class that exposes a RedirectActionName
public class LegacyRoute : Route
{
    public LegacyRoute(string url, string redirectActionName, IRouteHandler routeHandler)
        : base(url, routeHandler)
    {
        RedirectActionName = redirectActionName;
        Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index"}); // is not actually called
    }

    public string RedirectActionName { get; set; }
}

// The legacy route handler, used for getting the HttpHandler for the request
public class LegacyRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.HttpContext.Response.Write("success");
        return new LegacyHandler(requestContext);
    }
}

// The legacy HttpHandler that handles the request
public class LegacyHandler : MvcHandler
{
    public LegacyHandler(RequestContext requestContext) : base(requestContext)
    {
        requestContext.HttpContext.Response.Write("success");
        ProcessRequest(requestContext.HttpContext);
    }

    protected override void ProcessRequest(HttpContextBase httpContext)
    {
        string redirectActionName = ((LegacyRoute) RequestContext.RouteData.Route).RedirectActionName;
        var route = new Route(redirectActionName, ((LegacyRoute)RequestContext.RouteData.Route).Defaults, new MvcRouteHandler());

        // Copy all of the querystring parameters and put them within RouteContext.RouteData.Values
        var values = new Dictionary<string, object>();
        foreach (var s in RequestContext.RouteData.Values)
        {
            values.Add(s.Key, s.Value);
        }
        foreach (var s in httpContext.Request.QueryString.AllKeys)
        {
            values.Add(s, httpContext.Request.QueryString[s]);
        }
        var data = route.GetVirtualPath(RequestContext, new RouteValueDictionary(values));

        httpContext.Response.Status = "301 Moved Permanently";
        httpContext.Response.AppendHeader("Location", "/" + data.VirtualPath + "/");
        httpContext.Response.End();
    }
}

Then I simply add legacy routes to my route map:

routes.Insert(13, new LegacyRoute("search", "search/{query}", new LegacyRouteHandler()));
like image 156
Egor Pavlikhin Avatar answered Nov 15 '22 03:11

Egor Pavlikhin