Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to expose resource strings to JavaScript files in ASP.NET MVC?

Tags:

It's easy to use resource strings (.resx) in Razor view, but how to do that in JavaScript files? Currently I'm manually passing strings from Razor view to scripts in JavaScript constructor argument but I would like a way to do this more automatically so I don't have to pass each and every resource string that I need.

like image 471
Pol Avatar asked Apr 20 '13 16:04

Pol


People also ask

Can we use JavaScript in ASP NET MVC?

JavaScript can be used in asp.net mvc.


3 Answers

The solution I have used is to use a Razor to create a json object that contains all the resource strings for a given application area eg "Customers". Like so:

<script  type="text/jscript">

@{

    ResourceSet resourceSet = JsCustomersRes.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
    var sbInitial = " var CustomersResourceObj = {"; 
    var sb = new StringBuilder(sbInitial);
    var resEnum = resourceSet.GetEnumerator(); 
    while (resEnum.MoveNext()) 
    {
        if (sb.ToString() != sbInitial)
        {
            sb.Append(",");
        }
        sb.Append("\"" + resEnum.Key + "\":\"" + resEnum.Value.ToString().Replace("\r\n", "").Replace("\"", "\\\"") + "\"");
    } 
    sb.Append("}");
} 

@(Html.Raw( sb.ToString()));

The resource file "JsCustomersRes" can be placed along with the particular controller views directory or in the shared view directory. It should have "Custom Tool" set to "PublicResXFileCodeGenerator" in the file advanced properties.

You can then get the resource string from the json object in your script:

var resString = CustomersResourceObj[key];

where "key" is the key string of the resource string you want. Just add the Razor as a partial view to your layout page or individual page as you require and that's it!

like image 61
davaus Avatar answered Sep 25 '22 07:09

davaus


My solution is based on this http://codethug.com/2013/08/02/using-net-resources-in-javascript/ and quoting Tim Larson's (author) words:

We don’t have to do much to determine what culture to use. The web browser, when it hits the server, includes header information showing what cultures it supports. ASP.Net automatically puts this information into CultureInfo.CurrentUICulture. We pass this into the GetResourceSet method, which then returns the resource set that matches the current browser settings.

Thus, if the browser is set to French, the French resources, and only the French Resources, will be returned.

Steep 1. Create a resource file RLocalizedText.resx into App_GlobalResources folder. And create fill it with all the string.

Steep 2. Create ResourcesController

using System.Web.Mvc;

namespace PortalACA.Controllers
{
    public class ResourcesController : Controller
    {
        // GET: Resources
        public ActionResult Index()
        {
            Response.ContentType = "text/javascript";
            return View();
        }
    }
}

Steep 3. Create Index.cshtml view from ResourcesController

@using System.Collections
@using System.Globalization
@using System.Resources
@using Resources
@{
    Layout = null;
    // Get a set of resources appropriate to
    // the culture defined by the browser
    ResourceSet resourceSet =
      @RLocalizedText.ResourceManager.GetResourceSet
        (CultureInfo.CurrentUICulture, true, true);
}

// Define the empty object in javascript
var Resources = {};
@foreach (DictionaryEntry res in resourceSet)
{
    // Create a property on the javascript object for each text resource
    @:[email protected] = "@Html.Raw(
        HttpUtility.JavaScriptStringEncode(res.Value.ToString()))";
}

The choose where you want use it.

Steep 4A (Layout). If you want use it on whole site, then need put this script reference on _Layout (Shared View) over @RenderSection

<script src="@Url.Content("~/Resources/Index")"></script>
@RenderSection("scripts", required: false)

Steep 4B (View). If you want to see only in some views.

@section Scripts
{
  <script src="@Url.Content("~/Resources/Index")"></script>
}

Steep 5. Now it is the time to use it. Select a view where you need see the strings on Resources files and put this code.

@section Scripts
{
  <script>
    $(document).ready(function () {
      alert(Resources.General_Excepcion);
    });
  </script>
}

That's all Folks! Hope it help others!

like image 41
equiman Avatar answered Sep 27 '22 07:09

equiman


I would do something like the following:

<script type="text/javascript">
    var resourceStrings = {
        @foreach (var resource in ViewBag.Resources)
        {
            { '@resource.Key' : '@resource.Value' },
        }
    };
</script>

This assumes that you've created a dictionary of resource key/values and set a view bag property with the dictionary. You can then access those resources as a javascript object lookup.

$('label[name=gender]').html(resourceStrings['gender']);

You could potentially have a dictionary of dictionaries if you wanted to access keys by culture:

$('label[name=gender]').html(resourceStrings['en_US']['gender']);
like image 2
bitwalker Avatar answered Sep 28 '22 07:09

bitwalker