20

在 Razor 视图中使用资源字符串 (.resx) 很容易,但如何在 JavaScript 文件中做到这一点?目前我正在手动将字符串从 Razor 视图传递到 JavaScript 构造函数参数中的脚本,但我想要一种更自动地执行此操作的方法,因此我不必传递我需要的每个资源字符串。

4

7 回答 7

7

我使用的解决方案是使用 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”可以与特定的控制器视图目录或共享视图目录一起放置。它应该在文件高级属性中将“自定义工具”设置为“PublicResXFileCodeGenerator”。

然后,您可以从脚本中的 json 对象获取资源字符串:

var resString = CustomersResourceObj[key];

其中“key”是您想要的资源字符串的键字符串。只需根据需要将 Razor 作为部分视图添加到您的布局页面或单个页面,就是这样!

于 2013-05-29T01:18:33.630 回答
7

我的解决方案基于此http://codethug.com/2013/08/02/using-net-resources-in-javascript/并引用 Tim Larson 的(作者)的话:

我们不需要做太多的事情来确定使用什么文化。Web 浏览器在访问服务器时包含标头信息,显示它支持的文化。ASP.Net 自动将此信息放入 CultureInfo.CurrentUICulture。我们将它传递给 GetResourceSet 方法,然后该方法返回与当前浏览器设置匹配的资源集。

因此,如果浏览器设置为法语,则将返回法语资源,并且仅返回法语资源。

陡峭 1. 在 App_GlobalResources 文件夹中创建一个资源文件RLocalizedText.resx。并创建用所有字符串填充它。

2. 创建ResourcesController

using System.Web.Mvc;

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

陡峭 3.从 ResourcesController创建Index.cshtml视图

@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
    @:Resources.@res.Key = "@Html.Raw(
        HttpUtility.JavaScriptStringEncode(res.Value.ToString()))";
}

选择你想在哪里使用它。

陡峭的 4A(布局)。如果您想在整个站点上使用它,则需要将此脚本引用放在@RenderSection 上的_Layout(共享视图)上

<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>
}

这就是所有的人!希望它可以帮助别人!

于 2016-03-25T01:28:48.190 回答
2

我会做类似以下的事情:

<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']);
于 2013-04-20T19:05:34.557 回答
1

我更喜欢创建一个将所有资源作为属性的 Javascript 对象。我也避免创建局部视图。相反,我将所需的语言作为参数传递给脚本。这样,您可以在全局模板中添加脚本,而不是在每个页面中添加它。

基本上我有一个具有以下静态方法的辅助静态类:

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

现在调用这个脚本,我在默认模板中注册它(例如在~/Shared/_layout.cshtml

<script type="text/javascript" src="~/resources/?lang=@(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 就知道当前选择的语言。

于 2016-05-07T22:21:26.100 回答
1

已经提到了所有解决方案,无论好坏。为了完成,我想提出另一个解决方案:不要在 Javascript 中设置文本。

将 Javascript 中的单词添加到不直接从服务器加载的页面中,就像您将 css 写入 html 文件一样。

于 2018-06-06T13:40:56.497 回答
1

创建一个将您的资源集公开给 json 的操作

public class HomeController: Controller {

   [Route("localization.js")]
   public ActionResult Localization()
   {
       ResourceSet resourceSet = Globalization.Resources.ResourceManager.GetResourceSet(
                                       CultureInfo.CurrentUICulture, true, true);
       var result = resourceSet.Cast<DictionaryEntry>()
           .ToDictionary(x => x.Key.ToString(),
                    x => x.Value.ToString());

       return View((object)(JsonConvert.SerializeObject(result)));
   }

}

添加~/Views/Home/localization.cshtml包含内容的文件

@model string
@{ 
    Layout = null;
}
var Resources = @Html.Raw(Model);

Web.config中,添加处理程序localization.js

 <system.webServer>
   <handlers>
     <add name="Localization" path="*/localization.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
   </handlers>
 </system.webServer>

_Layout.cshtml在您或您要公开资源的任何地方调用操作

<script type="text/javascript">
    @(Html.Action("Localization", "Home"))
</script>

结果

<script type="text/javascript">
    var Resources = {"HelloWorld" : "こんにちは世界", "NiceJob": "いいね!" };
    //Sample usage
    console.log(Resources.HelloWorld);
    console.log(Resources.NiceJob);
</script>
于 2019-11-19T15:11:27.210 回答
0

您可以使用 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));
}
于 2013-04-20T17:05:15.143 回答