How to add route parameter before MVC sends route

I am trying to add support for different languages โ€‹โ€‹to an existing MVC 3 application. So far, my links have been

oldUrl -> myapp.com/Item/Details/5/some-title 

And there are links to the site from various places on the Internet. But now I want to change the url to include this language:

 newUrl -> kmyapp.com/en/Item/Details/5/some-title 

However, I want the oldUrl links to be valid. And the question is how can I do this ... The easiest way is to add another route, but I already have too many of them, and it becomes ugly, and when I create URLs from a page that is not a language, which links also have no language, so I have to do something else.

Another way would be to redefine something before MVC tries to map the request to a specific route, but has already parsed the request URL and populated the routeValues โ€‹โ€‹dictionary. Therefore, I can simply check the language and if it is not included in the route parameters, I can add it myself and call the implementation of the parent class to continue. Is it possible? What should I look for - UrlRoutingModule , MvcHttpHandler or something else? What can I override and how do I tell MVC to use my version?

Any other ideas would also be appreciated!

+7
source share
2 answers

Another way would be to redefine something before MVC tries to map the request to a specific route, but has already parsed the request URL and populated the routeValues โ€‹โ€‹dictionary. Therefore, I can simply check the language and if it is not included in the route parameters, I can add it myself and call the implementation of the parent class to continue. Is it possible?

Yes, it is possible.

You can override GetRouteData strong> in RouteBase , which will contain the URLs.

 public override RouteData GetRouteData(HttpContextBase httpContext) { string url = httpContext.Request.AppRelativeCurrentExecutionFilePath; } 

and in global.aspx add below code.

 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new MyUrlRoute()); // Add before your default Routes routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); 

For a more detailed implementation, see the URL manipulation blog implementing-routebase.html

+4
source

Of course, there are many solutions. I am going to show you two:

  • the one you control in your application
  • which you control outside of your application (in IIS)

Solution - MVC MVC Routing

Provide routing that spans old and new routing:

 routes.MapRoute( "New", "{lang}/{controller}/{action}/{id}", new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional }, new { lang = "en|de|it|es|fr" } ); routes.MapRoute( "NewEx", "{lang}/{controller}/{action}/{id}/{title}", new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional, title = UrlParameter.Optional }, new { lang = "en|de|it|es|fr" } ); routes.MapRoute( "Old", "{controller}/{action}/{id}", new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( "OldEx", "{controller}/{action}/{id}/{title}", new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional, title = UrlParameter.Optional } ); 

As you can see , I also specified the default language for the old routes , since it is not in the URL. Regardless of whether you want it or not, this is your own decision, but such routing allows you to not duplicate the actions of your controller. In any case, you will have to define a default language that can be provided this way.

There is another question, do you still want to support the old URLs, or do you prefer to redirect them (HTTP redirects to a constant status of 301).

Constant redirection

Change old routes to:

 routes.MapRoute( "Old", "{controllerOld}/{actionOld}/{idOld}", new { controller = "Redirect", action = "Permanent", id = UrlParameter.Optional } ); routes.MapRoute( "OldEx", "{controllerOld}/{actionOld}/{idOld}/{titleOld}", new { controller = "Redirect", action = "Permanent", id = UrlParameter.Optional, title = UrlParameter.Optional } ); 

Then write a controller class that redirects:

 public class RedirectController : Controller { public ActionResult Permanent(string controllerOld, string actionOld, string idOld, string titleOld) { return RedirectToRoutePermanent(new { lang = "en", controller = controllerOld, action = actionOld, id = idOld, title = titleOld }); } } 

Solution Two - IIS URL Rewrite Module

This solution is based on the IIS URL rewriting module, where you can rewrite any request without choosing the default language.

I am not going to write how URL Rewriting works, because there are many web resources with detailed information about this.

+11
source

All Articles