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())  
	);              Thats 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.