Подтвердить что ты не робот

Лучший способ показать строки ресурсов для файлов JavaScript в ASP.NET MVC?

Легко использовать строки ресурсов (.resx) в представлении Razor, но как это сделать в файлах JavaScript? В настоящее время я вручную передаю строки из представления Razor в скрипты в аргументе конструктора JavaScript, но мне хотелось бы, чтобы это сделать более автоматически, поэтому мне не нужно передавать каждую требуемую строку ресурсов.

4b9b3361

Ответ 1

Решением, которое я использовал, является использование Razor для создания объекта json, который содержит все строки ресурсов для данной области приложения, например "Клиенты". Например:

<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()));

Файл ресурсов "JsCustomersRes" можно разместить вместе с конкретным каталогом представлений диспетчера или в каталоге общего представления.  Он должен иметь "Custom Tool", установленный в "PublicResXFileCodeGenerator" в дополнительных свойствах файла.

Затем вы можете получить строку ресурса из объекта json в script:

var resString = CustomersResourceObj[key];

где "ключ" - это ключевая строка нужной строки ресурса. Просто добавьте Razor как частичный вид вашей страницы макета или отдельной страницы, как вам нужно, и что это!

Ответ 2

Мое решение основано на этом http://codethug.com/2013/08/02/using-net-resources-in-javascript/ и цитирует слова Тима Ларсона (автора):

Нам не нужно много делать, чтобы определить, какую культуру использовать. Паутина браузер, когда он попадает на сервер, содержит информацию заголовка, показывающую какие культуры он поддерживает. ASP.Net автоматически помещает эту информацию в CultureInfo.CurrentUICulture. Мы передаем это в GetResourceSet, который затем возвращает набор ресурсов, который соответствует текущим настройкам браузера.

Таким образом, если браузер установлен на французский, французские ресурсы и только Французские ресурсы, будут возвращены.

Крутой 1. Создайте файл ресурсов RLocalizedText.resx в папку App_GlobalResources. И залейте его всей строкой.

Крутой 2. Создайте ResourceController

using System.Web.Mvc;

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

Крутой 3. Создайте представление Index.cshtml из ResourceController

@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()))";
}

Выберите, где вы хотите его использовать.

Крутой 4A (Макет). Если вы хотите использовать его на целом сайте, то нужно поставить ссылку script на _Layout (общий вид) поверх @RenderSection

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

Крутой 4B (Вид). Если вы хотите видеть только в некоторых представлениях.

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

Крутой 5. Теперь пришло время его использовать. Выберите представление, в котором вам нужно увидеть строки в файлах ресурсов и поместите этот код.

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

Что все люди! Надеюсь, что это поможет другим!

Ответ 3

Я бы сделал что-то вроде следующего:

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

Предполагается, что вы создали словарь ресурсных ключей/значений и задали свойство пакета просмотра со словарем. Затем вы можете получить доступ к этим ресурсам в качестве поиска объектов javascript.

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

У вас может быть словарь словарей, если вы хотите получить доступ к ключам по культуре:

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

Ответ 4

Я предпочитаю создать объект Javascript, который обладает всеми ресурсами как свойствами. Также избегаю создания частичного представления. Вместо этого я передаю требуемый язык в качестве параметра в script. Таким образом вы можете добавить script в глобальном шаблоне, а не добавлять его на каждую страницу.

В основном у меня есть вспомогательный статический класс со следующим статическим методом:

    public static JavaScriptResult JavascriptResources(ResourceManager manager, string resourceObjectName, CultureInfo culture)
    {
        ResourceSet resourceSet = manager.GetResourceSet(culture, true, true);

        StringBuilder sb = new StringBuilder();

        sb.AppendFormat("var {0}=new Object();", resourceObjectName);

        var enumerator = resourceSet.GetEnumerator();
        while (enumerator.MoveNext())
        {
            sb.AppendFormat("{0}.{1}='{2}';", resourceObjectName, enumerator.Key,
                System.Web.HttpUtility.JavaScriptStringEncode(enumerator.Value.ToString()));
        }

        return new JavaScriptResult()
        {
            Script = sb.ToString()
        };
    }

В проекте я добавил следующий контроллер:

public class ResourcesController : Controller
{
    [OutputCache(Duration = 36000, VaryByParam = "lang")]
    // Duration can be many hours as embedded resources cannot change without recompiling.
    // For the clients, I think 10 hours is good.
    public JavaScriptResult Index(string lang)
    {
        var culture = new CultureInfo(lang);
        return Helpers.JavascriptResources(Resources.Client.ResourceManager,
            "Client", culture);
    }
}

Обратите внимание, что я добавил параметр, чтобы дать глобальному объекту javascript любое имя, которое вы хотите. В приведенном выше примере я мог получить доступ к таким переводам в JS:

alert(Client.Info_Message);

Теперь, чтобы вызвать этот script, я зарегистрирую его в шаблоне по умолчанию (например, в ~/Shared/_layout.cshtml)

<script type="text/javascript" src="~/resources/[email protected](ViewBag.Language)"></script>

Лучший способ для этого - создать фильтр действий для автоматического ввода языка в ViewData. Это можно сделать следующим образом:

public class LanguageInViewBagAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.Controller;
        if (controller != null)
            controller.ViewBag.Language = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
    }
}

Затем вы можете украсить контроллеры или действия там, где это применимо, например:

[LanguageInViewBag]
public class HomeController : Controller

или зарегистрируйтесь как глобальный фильтр в /App_start/Filters.cs

Примечание. В моей реализации предполагается, что вы настроили запрос Thread.CurrentThread.CurrentCulture для пользовательской культуры. Таким образом, actionfilter знает текущий выбранный язык.

Ответ 5

Вы можете сделать это более грациозно, используя AJAX и JSON ActionResult.

<button />
<label for="gender"></label>

<script type="text/javascript">
    $("button").click(function () {
        $('label[for=gender]').load('@Url.Action("ResourceLabel", new { labelKey = "Gender" })');
    });
</script>

И серверная сторона, очень упрощенная, но вы получаете идею:

public ContentResult ResourceLabel(string labelKey) {
    return Content(ResourceClass.GetString(labelKey));
}