So you want to create a multilingual project in MVC4 or MVC5? You are new to ASP.NET MVC and you are looking for a working solution, easy to understand and easy to implement? You are in the right place. This solution has been used for a couple of live websites and it worked quite well. Also the Frontend Developer that worked with me was quite happy with the solution. Read on to understand why.
You will find online a couple of tutorials and approaches. One I liked and followed is Creating a Bilingual ASP.NET MVC 3 Application – Part 2: it offers a working culture detection based on the user browser's settings and it allows the user to browse the site also by entering in the url -just after the domain name- the language abbreviation (like this: http://www.example.com/en/Home/Index ). The solution in the above tutorial allows the developer to save the translations in .resx files (same principle for LocalResources and GlobalResources).
However, the Cultural View Engine for MVC tutorial (or better: Custom View Engine for Localized Views with ASP.NET MVC Razor - for razor cshtml pages) offers the same browsing routes and the possibility to save the translations directly in the view files, making the editing much more user friendly than editing the .resx files in Visual Studio (which, for long and formatted texts, is not user friendly at all).
When I studied these 2 approaches/tutorials, I decided to mix them, making the developer life much easier and flexible.
Imagine the following scenario:
- Global.resx file for all the common translations for classic UI labels, buttons, tooltips etc.
- a default ~/Views folder containing the main views and partial views (e.g. Index.cshtml, About.cshtml, _Header.cshtml, _Footer.cshtml) with localized content taken from the .resx files, like this @Global.FooterText
- some views containing the content not as variable like @Global.FooterText but copied and pasted there directly e.g. "Copyright Foo Bar 2013", saved e.g. in Example.cshtml
- the same views as above, with the same name as above and a language suffix e.g. Example.de.cshtml and content translated directly in that file (in this example, "de" is for German)
Resources
- Visual Studio Community 2013 (it's like the "Pro" version, but for FREE! See license details)
- Download and install MVC 4 (not needed if you are using Visual Studio 2013, you probably use MVC5)
- Download and install the NuGet package manager plugin for Visual Studio (not needed if you have Visual Studio 2013, it should be installed already)
- Configure Visual Studio to restore the NuGet packages automatically
My solution
Download
- MultilanguageMVC4-2013.10.07a.zip (use this as reference only. Create your own project in Visual Studio 2013 in MVC5 to have all the updated packages and dependencies, bootstrap etc.)
- Update 2016-05-13 I didn't check it but you may have a look at Xavier educa02 on github (repository based on this work)
Note: in the Areas you can't have a controller with the same name of a standard controller (or vice-versa). Every controller must have a unique name.
You may find these 2 helpers quite handy (I use GetLanguage in my controllers when I need to process contents based on the language, in example to build an URL I have to insert in a mail sent to the user, or similar things):
- CultureManager.GetLanguage()
- CultureManager.GetCulture()
To use/implement this solution in your own project in your solution you need about 5 Minutes (+ a few more minutes to add new languages or remove the ones you do not want to support). Just follow this simple procedure:
- copy all the files you find under "Code" and put them in a separate class library (and add a reference to it), or copy the "Code" folder directly in your project.
- Check the modifications to the global.asax.cs file and apply them to your global.asax.cs file (and update your default route in case it's not Home/Index).
- If you want more languages or remove some from the default ones I added (en, de, fr, it) you must edit the CultureManager.cs file. Check the constants at the top and the method InitializeSupportedCultures(). If you need more precision in the culture (in my case I use only the 2 letters ISO abbreviation) you may do some refactoring.
Credits
My solution is based on these 2 tutorials:
- Creating a Bilingual ASP.NET MVC 3 Application – Part 2
- Custom View Engine for Localized Views with ASP.NET MVC Razor
I downloaded and updated the first tutorial solution and added the LocalizedViewEngine.cs from the 2nd tutorial. Then updated the global.asax.cs file accordingly.
As some people asked for it, I added also an example with Areas. If you don't need areas, simply delete the "Areas" folder, save all and re-compile.
Enjoy.
UPDATES
Update 2015-02-19
Seems that this blog post is still helpful. Good news, this solution works of course also with MVC5. Don't update my demo project to MVC5, start a fresh one and follow the procedure to add multi-language views support.
Update 2013-10-21
Added some more useful information on how to use this solution. Hopefully it should be quite easy to implement this in your solution.
Update 2013-10-07
As some people asked for it, I added an example with Areas. I added an Area called "Admin", a controller called "Account" and 2 test Views: Index and Test. I added a localized Index.de and for Test I used the .resx resources. To register the new area and make it work with my multi language support, see Areas\\Admin\\AdminAreaRegistration.cs. Hope this helps.
Update 2013-06-05
I'm not 100% about this, but my solution can lead to caching problems.
Symptom: after changing the language to xx I keep seeing the contents of my main View PageFoo.cshtml and not the contents in PageFoo.xx.cshtml.
Solution: I needed -for my production website- to keep the debug option in the web.config file, more precisely in the tranform web.config.live in Visual Studio I had to keep this (as I use the publish function):
<compilation xdt:Transform="RemoveAttributes(debug)" />
If you don't have a transform file, then the option in the web.config file has to be:
<compilation debug="true" targetFramework="4.0" />