5

I have a site that supports localization. I would like to be able to switch between English and French.

Let say the user is currently at URL: http://www.example.com/**en**/Home

I would like to redirect to: http://www.example.com/**fr**/Home

If the user click on a "French" link how to change the URL part to "fr" yet not change the "Home" part of the URL (basically I want preserve the current location of the user)

Hope my question makes sense! I'm probably missing something very basic?

EDIT: Kind of found a solution.

<%= Html.ActionLink("Français", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { culture = "fr" }, null)%>
<%= Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { culture = "en" }, null)%>

This maintains the action/controller of the current URL. Maybe there's a cleaner solution?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
vidalsasoon
  • 4,365
  • 1
  • 32
  • 40

3 Answers3

2

In your Global.asax

 routes.MapRoute(
   name: "LocalizedRoute",
   url: "{language}/{controller}/{action}/{id}",
   defaults:
     new
     {
       language= "fr",
       controller = "Home",
       action = "Index",
       id = UrlParameter.Optional 
     },
   constraints: new { language= @"[a-z]{2}" });

And you can have access to the language with the variable language in your controller

To generate a link:

<%= Html.ActionLink("French", ViewContext.RouteData.Values["action"], new { language = "fr" }) %>

And you can make a base class controller with this property:

public string Language { get { return this.Routedata["language"]; } }
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Gregoire
  • 24,219
  • 6
  • 46
  • 73
  • this is good but what if they are not currently in "Home" but want to change languages? They could be anywhere on the site when they decide to change languages so I don't want to force them back to "Home" – vidalsasoon Apr 08 '10 at 21:46
  • having the catchall route using the language parameter will make it work anywhere your user is when changing language. And you should of course have the language parameter on all your route with a default value. – Stéphane Apr 08 '10 at 22:22
  • @vidalsasoon: Home and index are just default values, so this route is valable for all other actions – Gregoire Apr 08 '10 at 22:48
  • I think there's a misunderstanding. <%= Html.ActionLink("French", "Home", new { language = "fr" }) %> takes me to the "Home" page because it's hardcoded. What if the user is currently at "Services" and not "Home"? Clicking that ActionLink would take them away from "Services" which is not good. – vidalsasoon Apr 09 '10 at 01:27
  • @vidalsasoon I have updated the link generation in order to match your requirements – Gregoire Apr 09 '10 at 13:10
  • I had to use ViewContext.RouteData.Values["action"].ToString(). Other than that, works like a charm. – bluedot Jan 11 '18 at 13:04
1

I made a extension for RouteValueDictionary to solve this problem:

public static RouteValueDictionary SetValue(this RouteValueDictionary dictionary, string key, object value)
{
    RouteValueDictionary rvd = new RouteValueDictionary(dictionary);
    rvd[key] = value;
    return rvd;
}

Now you can use this as follow in the html template:

<div id="head">
    @Html.RouteLink("DE", ViewContext.RouteData.Values.SetValue("language", "de")) |
    @Html.RouteLink("FR", ViewContext.RouteData.Values.SetValue("language", "fr")) |
    @Html.RouteLink("IT", ViewContext.RouteData.Values.SetValue("language", "it")) |
    @Html.RouteLink("EN", ViewContext.RouteData.Values.SetValue("language", "en"))
</div>

The extension don't modifiy the RoutData.Values collection, it makes a copy and you can override the desired value.

M.Winkler
  • 21
  • 4
0

I would suggest making the urls in this format:

http://www.mysite.com/Home/en

Then you can make actions as simple as this:

<%= Html.ActionLink("Francais", "Home", "MyController", new { id = "fr" }), null %>
<%= Html.ActionLink("English", "Home", "MyController", new { id = "en" }), null %>

Then in your controller have an action:

public ActionResult Home(string id)
{
    if(id == "en"){ // do something } 
    else if(id == "fr") { // do something else }
    return View();
}

Global.asax Route

routes.MapRoute(
   "HomeLanguageRoute", // Route name
   "MyController/Home/{id}", // URL with parameters
   new { controller = "MyController", action = "Home", id = "" }    // Parameter defaults
);
Gabe
  • 49,577
  • 28
  • 142
  • 181
  • I think its better to keep the language in the beginning. Lets say you have deeper links like: /Catalogue/en/Electronics/Radio_a. This doesnt look nice. There should be a new Parameter in the routing for the language. – Mathias F Apr 08 '10 at 21:27