Globalizing Javascript with .NET Resources Using ASP.NET MVC

Sometimes you already have a .NET Resources to translate your application and now you need to use the same messages in Javascript. In this post I will show you how to create an ASP.NET MVC action and return a javascript object containing the messages, all that respecting the culture setted in the Thread.CurrentUICulture.

The first thing I will do is to create a base controller with the action that will do the job to create the javascript object. With this base controller I can inherit my other controllers and have the solution shared in any route that I am.

public abstract class BaseController : Controller
{
    public ActionResult ResourceScript(string id, string culture)
    {
        var sb = new System.Text.StringBuilder();

        var resourceType = Type.GetType(id);

        sb.Append(resourceType.Name + " = {");

        var resourceProps = resourceType.GetProperties();

        int count = 0;

        System.Resources.ResourceManager rm = null;
        foreach (var prop in resourceProps)
        {
            var value = prop.GetValue(null, null);
            if (value is System.Resources.ResourceManager)
            {
                rm = value as System.Resources.ResourceManager;
                break;
            }
        }

        if (rm != null)
        {
            var rs = rm.GetResourceSet(new System.Globalization.CultureInfo(culture), true, true);
            if (rs != null)
            {
                var enumerator = rs.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    if (count > 0)
                        sb.Append(",");
                    if (enumerator.Value is string)
                    {
                        sb.Append("\n\t" + enumerator.Key + ": \"" + enumerator.Value + "\"");
                        count++;
                    }
                }
            }
        }

        sb.Append("\n}");

        return File(System.Text.Encoding.UTF8.GetBytes(sb.ToString()), "text/javascript");
    }
}

The action method expects the id that will be the type name of the resources and the culture. The javascript object will have the name of the resources. I get the properties of the Resource type and search for the ResourceManager, with this I can get each key and value and create the javascript object properties. The final step is return the content created indicating that the result is a file of type text/javascript.

Instead to type the Resource type, the culture and the script tag each time, I will create an extension for HtmlHelper to make the things easier.

public static class HtmlHelperExtension
{
    public static IHtmlString IncludeResourceScript(this HtmlHelper htmlHelper, string typeName)
    {
        var type = Type.GetType(typeName);
        return htmlHelper.IncludeResourceScript(type);
    }

    public static IHtmlString IncludeResourceScript(this HtmlHelper htmlHelper, Type resourceType)
    {
        return htmlHelper.IncludeResourceScript(resourceType, Thread.CurrentThread.CurrentUICulture.Name);
    }

    public static IHtmlString IncludeResourceScript(this HtmlHelper htmlHelper, string typeName, string idioma)
    {
        var type = Type.GetType(typeName);
        return htmlHelper.IncludeResourceScript(type, idioma);
    }

    public static IHtmlString IncludeResourceScript(this HtmlHelper htmlHelper, Type resourceType, string idioma)
    {
        var viewContext = htmlHelper.ViewContext;
        var controllerName = viewContext.RouteData.Values["controller"];
        var actionName = "ResourceScript";
        string applicationPath = HttpContext.Current.Request.ApplicationPath;
        if (applicationPath == "/")
            applicationPath = String.Empty;
        var resourceName = resourceType.AssemblyQualifiedName;
        var sb = new StringBuilder();
        sb.AppendFormat("<script src=\"{0}/{1}/{2}/?id={3}&culture={4}\" type=\"text/javascript\"></script>", applicationPath, controllerName, actionName, resourceName, idioma);
        return new HtmlString(sb.ToString());
    }
}

Now we just need to use the code created. I have a Resource called Translation with the keys and values:

1) Hello = Olá

2) World = Mundo

is very important to change the Access Modifier to public.

Below is the controller and the Index.cshml

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }
}
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div id="divHelloWorld"> 
    </div>
    @Html.IncludeResourceScript(typeof(GlobalizingJavascriptWithNetResources.Resources.Translation))
    <script type="text/javascript">
        document.getElementById("divHelloWorld").innerHTML = Translation.Hello + Translation.World;
    </script>
</body>
</html>

And this is it!!

Globalizing Javascript with .NET Resources Using ASP.NET MVC

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s