ASP.Net MVC routing legacy URLs passing querystring Ids to controller actions

我只是一个虾纸丫 提交于 2019-11-26 18:25:13

问题


We're currently running on IIS6, but hoping to move to IIS 7 soon.

We're moving an existing web forms site over to ASP.Net MVC. We have quite a few legacy pages which we need to redirect to the new controllers. I came across this article which looked interesting: http://blog.eworldui.net/post/2008/04/ASPNET-MVC---Legacy-Url-Routing.aspx

So I guess I could either write my own route handler, or do my redirect in the controller. The latter smells slightly.

However, I'm not quite sure how to handle the query string values from the legacy urls which ideally I need to pass to my controller's Show() method. For example:

Legacy URL:

/Artists/ViewArtist.aspx?Id=4589

I want this to map to:

ArtistsController Show action

Actually my Show action takes the artist name, so I do want the user to be redirected from the Legacy URL to /artists/Madonna

Thanks!


回答1:


depending on the article you mentioned, these are the steps to accomplish this:

1-Your LegacyHandler must extract the routes values from the query string(in this case it is the artist's id) here is the code to do that:

 public class LegacyHandler:MvcHandler
    {
        private RequestContext requestContext;
        public LegacyHandler(RequestContext requestContext) : base(requestContext)
        {
            this.requestContext = requestContext;
        }

        protected override void ProcessRequest(HttpContextBase httpContext)
        {
            string redirectActionName = ((LegacyRoute) RequestContext.RouteData.Route).RedirectActionName;

            var queryString = requestContext.HttpContext.Request.QueryString;
            foreach (var key in queryString.AllKeys)
            {
                requestContext.RouteData.Values.Add(key, queryString[key]);
            }

            VirtualPathData path = RouteTable.Routes.GetVirtualPath(requestContext, redirectActionName,
                                                                    requestContext.RouteData.Values);
            httpContext.Response.Status = "301 Moved Permanently";
            httpContext.Response.AppendHeader("Location", path.VirtualPath);

        }
    }

2- you have to add these two routes to the RouteTable where you have an ArtistController with ViewArtist action that accept an id parameter of int type

    routes.Add("Legacy", new LegacyRoute("Artists/ViewArtist.aspx", "Artist", new LegacyRouteHandler()));

    routes.MapRoute("Artist", "Artist/ViewArtist/{id}", new
        {
         controller = "Artist",
         action = "ViewArtist",
        });

Now you can navigate to a url like : /Artists/ViewArtist.aspx?id=123

and you will be redirected to : /Artist/ViewArtist/123




回答2:


I was struggling a bit with this until I got my head around it. It was a lot easier to do this in a Controller like Perhentian did then directly in the route config, at least in my situation since our new URLs don't have id in them. The reason is that in the Controller I had access to all my repositories and domain objects. To help others this is what I did:

routes.MapRoute(null,
    "product_list.aspx", // Matches legacy product_list.aspx
     new { controller = "Products", action = "Legacy" }
);

public ActionResult Legacy(int catid)
{
    MenuItem menuItem = menu.GetMenuItem(catid);
    return RedirectPermanent(menuItem.Path);
}

menu is an object where I've stored information related to menu entries, like the Path which is the URL for the menu entry.

This redirects from for instance

/product_list.aspx?catid=50

to

/pc-tillbehor/kylning-flaktar/flaktar/170-mm

Note that RedirectPermanent is MVC3+. If you're using an older version you need to create the 301 manually.



来源:https://stackoverflow.com/questions/817325/asp-net-mvc-routing-legacy-urls-passing-querystring-ids-to-controller-actions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!