views:

666

answers:

3

I'm trying to implement localization with routes

I have the following:

routes.MapRoute( "DefaultLocalized", 
                 "{lang}/{controller}/{action}/{id}",
                 new { controller = "Home",
                       action = "Index",
                       id = "",
                       lang = "en" }
               );

routes.MapRoute( "Default",
                 "{controller}/{action}/{id}",
                 new { controller = "Home",
                       action = "Index",
                       id = "" }
               );

When I call my page domain/en/home/index, it works fine but when i call domain/home/index I get error 404: resource cannot be found.

Also when I'm at domain/en/home/index and I click a secured page I get redirected to domain/Account/login how can I be redirected to domain/en/Account/login?

Also when I get an application error how can I be redirected to domain/en/home/error?

The real question is how can I implement localization with language as a route parameter?

+4  A: 

The routes will match, by default, left-to-right, so "domain/home/index" will match first to lang=domain, controller=index, action (default to index), id (default to 0/null).

To fix this, I believe you can specify a regex on the MapRoute (matching, for example, languages with exactly 2 characters) - it has changed at some point, though... (sorry, no IDE at the moment, so I can't check exactly).

From memory, it might be:

routes.MapRoute( "DefaultLocalized", 
             "{lang}/{controller}/{action}/{id}",
             new { controller = "Home",
                   action = "Index",
                   id = "",},
             new { lang = "[a-z]{2}" }
           );

Note that you probably aren't going to want every action to take a "string lang", so you should handle the "lang" part of the route either in a base-controller, or an action-filter (in either case, presumably add the info to the ViewData).

Marc Gravell
Just to avoid same confusion as happened to me. You don't have add lang parameter to each controller action or mess with RouteData. It is just nice to handle language in global manner.
Jakub Šturc
+1  A: 

Add a contraint as new {lang = "[a-z]{2}"}.

Additionally, drop the default lang = "en". If you don't, the routing will grab the language rule when you are browsing it without it. So if you are looking at domain and you select About, it would use domain/en/Home/About instead of the more simple domain/Home/About

eglasius
+1  A: 

You could also introduce a constraint even tighter than Marc Gravell and Freddy Rios.

something like "en|de|fr|es". This would mean hardcoding the languages but usually these are few and known.

Andrei Rinea