Легко использовать строки ресурсов (.resx) в представлении Razor, но как это сделать в файлах JavaScript? В настоящее время я вручную передаю строки из представления Razor в скрипты в аргументе конструктора JavaScript, но мне хотелось бы, чтобы это сделать более автоматически, поэтому мне не нужно передавать каждую требуемую строку ресурсов.
Лучший способ показать строки ресурсов для файлов JavaScript в ASP.NET MVC?
Ответ 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));
}