This is something I researched recently while working on an ASP.NET MVC application. My goal was to localize JavaScript messages based on user preferences. In this post I am going to document the approach I settled on. I am going to test based on browser culture and also drive the application based on the same preferences.
First of all, here is how I am setting up for testing using Internet Explorer. Go to Settings menu, then select Internet Options. You will see Languages button.
Once I am there, I am going to add Spanish for testing.
I can now test by moving preferred language up and down.
Now, in my controller (you can do in the base controller or any other place that can e hit before any code that manipulates the user interface, such as labels or JavScript. Here is an example from Home controller in a brand new MVC app. If you add a brand new MVC project, you will see that controller. You can always create a base class and put your code there, which is what I did.
using System.Globalization;
using System.Threading;
using System.Web.Mvc;
namespace LocalizeJavaScriptMvc.Controllers
{
public class HomeController : Controller
{
private void SetCulture()
{
if (HttpContext.Request.UserLanguages != null &&
HttpContext.Request.UserLanguages.Length > 0)
{
Thread.CurrentThread.CurrentCulture =
new CultureInfo(HttpContext.Request.UserLanguages[0]);
Thread.CurrentThread.CurrentUICulture =
Thread.CurrentThread.CurrentCulture;
}
}
public ActionResult Index()
{
ViewBag.Message = MainResource.Title;
return View();
}
public ActionResult About()
{
return View();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
SetCulture();
}
}
}
So, now my main thread has been setup. Next, I am going to create two resource files. One with code generation, specifically MainResource.resx. Just Select Add New Item from project menu, and select new Resource, then give it the name as above. Repeat the step, this type using MainResource.es.resx. Pull up MainResource in the editor window, add some strings and set it’s access modifier to public:
Now, to JavScript. My experience in the language is somewhat limited, but I dutifully read the most recommended book on the language, JavaScript – the Good Parts many months back. So, I added brand new JavaScript file to my project with my class that will be responsible for localization – mainApp.js.
if (!window.resourceProvider) {
window.resourceProvider = {
message1: ”,
message2: ”
};
}
My resourceProvider class has two properties, that I set to empty strings. I like defining properties because I get IntelliSense when I do. In my “master page” – layout page – _Layout.cshtml I need to include my new script
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/mainApp.js")" type="text/javascript"></script>
</head>
The last step is to populate my message1 property with the actual text. I will do that in the bottom of the view:
</div>
</body>
</html>
<script type="text/javascript">
resourceProvider.message1 = ‘@(MainResource.Message1)’;
</script>
Now, I just need to call it from JavaScript. For testing, I am just adding a button ti Index.cshtml and script to invoke Click event with a simple alert:
@using LocalizeJavaScriptMvc
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
<button id="clickhere">@MainResource.Click</button>
</p>
<script type="text/javascript">
$().ready(function () {
$(‘#clickhere’).click(function () {
alert(resourceProvider.message1);
});
})
</script>
As you can see, I am localizing button text and using my resourceProvider class with its message1 property to localize the alert.
To test, I just set preferred language in browser to English and Spanish, and run the app twice to test.
You can download solution at http://dotnetspeak.com/Downloads/LocalizeJavaScriptMvc.zip
Please let me know if you have any comments regarding this solution.
Thanks.