Localization with ASP.NET MVC using Routing
In this article I am showing how to localize pages with ASP.NET MVC. Therefor I create a new Type of Route
and a special RouteHandler
.
Perhaps I will use ASP.NET for a new multilingual website, therefore I had to figure out how to create localized pages with ASP.NET MVC. It took a lot of time to search for some implementations, but I could not find any useable code for my problem, so here is my approach.
What I want
For my site the URL schema should look like this in general:
/{culture}/{site}
Imagine there is a page called FAQ, which is available in different languages. Here are some sample URLs for these pages:
/en-US/FAQ
/de-DE/FAQ
/de-CH/FAQ
Additional I want to have some pages which are in a single language. The backend to modify the FAQ pages for example just needs to be in English.
My approach
My idea was to automatically add the {culture} parameter to those routes, which should be multilingual. I created a new class “MultiLingualMvcRouteHandler”. This Routehandler gets the culture from RouteData and sets CurrentCulture as well as CurrentUICulture. You can use this informations in custom HTMLHelpers.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1
{
public class MultiLingualMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
{
String Culture = requestContext.RouteData.Values["culture"].ToString();
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfoByIetfLanguageTag(Culture);
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfoByIetfLanguageTag(Culture);
return base.GetHttpHandler(requestContext);
}
}
}
I also created a new Subtype of Route
. Mainly this new Route is to discern between non multilingual and multilingual Routes. As you can see there are no additional methods or attributes yet.
public class MultiLangualRoute : Route
{
public MultiLangualRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { }
public MultiLangualRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler) { }
public MultiLangualRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler) : base(url, defaults, constraints, routeHandler) { }
public MultiLangualRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, constraints, dataTokens, routeHandler) { }
}
After that I registered my FAQ page like in the global.asax. At the bottom of the method I check the RoutesCollection for Routes of my new type MultilingualRoute. The URLs of those types are expanded at the beginning with {culture}. The default culture is set to en-US.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
new Route("Backend/Edit/FAQ",
new RouteValueDictionary(new { controller = "CMS", action = "Edit", Id = 1}),
new System.Web.Mvc.MvcRouteHandler())
);
routes.Add(
new MultiLangualRoute("FAQ",
new RouteValueDictionary(new { controller = "CMS", action = "Show", Id = 1 }),
new MvcApplication1.MultiLingualMvcRouteHandler())
); That’s it so far. Hope this is helpfull for someone else.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
foreach (Route r in routes)
{
if (r.GetType() == typeof(MultiLangualRoute))
{
r.Url = "{culture}/" + r.Url;
r.Defaults.Add("culture", "en-US");
}
}
}
You can create links like this:
<%= Html.ActionLink("Show me the FAQ in German", "Show", "CMS", new {id = 1, culture="de-DE"}) %>
If you want to generate a link to a page with the current culture, you can use the ActionLink helper without setting the culture.
<%= Html.ActionLink("Show me the FAQ", "Show", "CMS", new {id = 1}) %>
That’s it so far. Hope this is helpfull for someone else.