3

I've set up my application so that the contents are read from different RESX files, according to the pattern that the router recognizes. Every page is accessible in a certain language depending on the first part of the URL.

routes.MapRoute(
  name: "Localization",
  url: "{lang}/{controller}/{action}/{id}", ...
);

When I'm testing with no specification, I get to the English version of my Lingo.REXS and when I put in se, I get to the Swedish version, i.e. Lingo.se.RESX. Everything's fine this far.

However, I'm not sure how to let the user control the setting of the language. I don't want it to be automatic nor assumed based on the browser's settings, geo-data etc. I basically want three flags (img controls) that somehow magically set that user (or at least that browser session) to be routable with the prefix corresponding to the language of the flag clicked.

So, we have /se/Home/About and /ge/Home/About. The user clicks on the German flag - how do we route them to the latter? And if they click on the Swedish flag - how do we route them to the former?

I've verified with this blog but it doesn't address the actual issue with how to route into a certain language depending on the clicked flag image. I've also found this blog but I simply don't understand how they do it. I see a bunch of calls to a DB so I suspect that it's not based on RESX files (and my understanding is that it's the proper way to go), although there's also some reference to @TestResource.

Right now I'm confused and uncertain. Any suggestions or clarifications?

0

1 Answer 1

3

There is a somewhat non-intuitive feature of MVC that makes this really easy. MVC automatically reuses any route values from the request. So all of your URLs will automatically "inherit" the culture - there is no need to specify it explicitly in ActionLink.

The one exception is during language selection. But you can take advantage of this same routing behavior to build a common header or footer in your _Layout.cshtml. Whatever route values the current page has will be inherited - all you need to do is specify controller, action, and culture.

@{ 
    var routeValues = this.ViewContext.RouteData.Values;
    var controller = routeValues["controller"] as string;
    var action = routeValues["action"] as string;
}
<ul>
    <li>@Html.ActionLink("Swedish", @action, @controller, new { lang = "se" }, new { rel = "alternate", hreflang = "se" })</li>
    <li>@Html.ActionLink("English", @action, @controller, new { lang = "en" }, new { rel = "alternate", hreflang = "en" })</li>
</ul>

As mentioned previously, all other links on the page will automatically be passed a culture from the current context, so they will automatically stay within the same culture. There is no reason to pass the culture explicitly in those cases.

@ActionLink("About", "About", "Home")

With the above link, if the current URL is /Home/Contact, the link that is generated will be /Home/About. If the current URL is /en/Home/Contact, the link will be generated as /en/Home/About.

Reference: ASP.NET MVC 5 culture in route and url

Sign up to request clarification or add additional context in comments.

5 Comments

Hmm... I recognize the insightfulness of your replies, so (now, that the sucking-up is delivered) I wonder if you mean that I've done way too much by implementing the special route and localization attribute. Are you saying that I only need to place a link with culture for the three languages somewhere in _Layout.cshtml and once the user click there (hence selecting the culture), it will live on? It can't be that easy... Can it?
Yes, that is correct. It is that easy. But, it does depend on there being a route to match the route value (which you have shown in your question). See my linked answer for how to handle the "default" language.
It's freaking awesome. It feels like a bug (that in this case is extremely helpful, though) but the stupid re-routing only handles the suffix after the second slash. That's great! Thanks.
But does this work for multiple concurent sessions of different languages? Surely changing the global culture affects them all ?
The above code isn't dealing with the culture, it is simply building a hyperlink with the culture string in it. If you follow through to ASP.NET MVC 5 culture in route and url, there is a CultureFilter which sets the culture based on the URL. This culture is not global, it is associated with the current thread, and will not affect other users of the application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.