A common complaint when faced with localizing ASP.net MVC pages is that littering your code with tonnes of runat=”server” tags breaks the “purity” of the MVC model. Regardless of how meaningful that debate is, there is a way to achieve globalisation without server controls.
I’m going to walk you through a sample implementation which should hopefully make this clearer. As a standard disclaimer, none of this code has been tested in a production environment and I wouldn’t advise implementing it blindly.
I’m going to attempt to play this out mostly in screenshots…
The Idea
- The required language is stored in a database / session / extrapolated from the Url route information
- Your view pages derive from the type TranslatableViewPage
- This page adds support for a LanguageCode property that you can make use of inside the view along with adding a class implementing ITranslator, a class that provides hooks into a translation database.
- This controller add a method called ViewInLanguage(string languageCode) that you use instead of View() or View(model) to return your Asp.net MVC view.
Class Layout
The following is built upon the standard Asp.net MVC starter project for the sake of illustration.
Implementation
First, configure the translation settings and register your translator…
You need to configure a fail-safe default language code and a type that implements ITranslator. This translator will be responsible for doing the heavy lifting. Ideally we’d add some inversion of control here to allow you to define the translator implementation at configuration time, but that’s outside of the scope of this example. I’ve implemented a very crude resource .resx translator for the example.
Next, make your controllers inherit from TranslatableController
Once inherited, switch from using the View(); method to ViewInLanguage() passing in your desired language code (gathered from the user session / database / Url route).
Then set your view type (or derive your view from) TranslatableViewPage…
Once your view is inheriting from TranslatableViewPage, you’ll have access to an instance of your specified Translator and the LanguageCode inside the view which you can use in a manner similar to the built in HtmlHelper class to access your translated strings.
How It Works
The TranslatableController provides you with ViewInLanguage and when called generates the standard MVC ActionResult. This ActionResult will be a ViewResult, which is then wrapped in a LocalizedViewResult wrapper class adding a LanguageCode.
When ExecuteResult is called on the LocalizedViewResult to render the view, the LanguageCode is placed in the TempData array in the TranslatableViewPage. Then, when the OnInit(EventArgs e) method is called on the TranslatableViewPage, this LanguageCode is extracted and placed in the LanguageCode property on the page. In addition to this the page provides a constructed instance of ITranslator which you can use in your views to source translated data as the page is rendered.