.NET中的Javascript本地化

3
我正在尝试确定将本地化实现到我们的一个Web应用程序中的最佳方法。该应用程序将拥有大量的JavaScript文件,这些文件也需要进行本地化。
本地化.net代码是很容易的。我们有一个名为WebResources.resx的文件,其中包含所有英语字符串(我们的后备语言)。然后,我们只需添加带有替代本地化信息的其他文件(例如:WebResources.es-mx.resx)。然后,.Net几乎会自动处理剩下的部分。
非常不错。但是当涉及到JavaScript时,就不那么快了。根据MSDN的建议
您为每种支持的语言和文化创建单独的脚本文件。在每个脚本文件中,您都包含一个以JSON格式表示的对象,其中包含该语言和文化的本地化资源值。
这似乎是我想要避免的维护噩梦。此外,我还想避免使用asp.net ScriptManager。因此,我想到了在我的.js文件中使用资源文件。例如foobar.js
function showGenericError(){
     alert('<% =Resources.WebResources.JsGenericError %>');
}

很遗憾,这不起作用,因为.NET似乎不会对.js文件进行任何处理。所以我得到的下一个想法来自于此线程上的答案。它建议创建一个包含所有语言字符串的JavaScript文件。但是,这会造成资源浪费,因为在运行时我只需要一种语言,而不是所有语言。
这导致我想要实现的解决方案。我计划有一个通用处理程序,编写出本地化为当前用户所需语言的JSON。以下是.ashx页面的示例:
public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "application/json";

        StringBuilder json = new StringBuilder();
        using (StringWriter jsonStringWriter = new StringWriter(json))
        {
            using (JsonTextWriter jsonWriter = new JsonTextWriter(jsonStringWriter))
            {
                jsonWriter.WriteStartObject();                

                jsonWriter.WritePropertyName("genericErrorMessage");
                jsonWriter.WriteValue(Resources.WebResources.GenericErrorMessage);

                jsonWriter.WriteEndObject();
            }
        }
        context.Response.Write("var webResources = " + json.ToString());
}

在我的网页头部,我会有以下内容:
<script type="text/javascript" src="js/webResources.js.ashx"></script>

那么我的js文件将如下所示:
function showGenericError(){
     alert(webResources.genericErrorMessage);
}

看起来似乎太容易了,对吧?那么我的问题是,这有意义吗?我是否遗漏了某些“陷阱”?有什么缺点吗?有更好的方法吗?


1
有道理,不过你可能需要想出一种方法,在构建时生成每个目录文件的 JavaScript 版本,以便浏览器可以缓存数据。现在的情况是,每次页面查看都必须重新下载目录。 - Pointy
看起来最终你得到的东西与你的MSDN文章推荐非常相似,即一个包含单个语言的JSON序列化本地化的js文件。 - CodesInChaos
CodeInChaos,是的,有点绕。但我避免使用ScriptManager或编写逻辑来确定要加载哪个JS文件。真正的优势在于,如果一个语言文件中缺少关键字,它会很好地降级。 - roto
在我看来,对于所有语言使用相同的JavaScript URL 是一个不好的想法。这会使缓存变得更难以正确处理。例如,如果用户切换语言... - CodesInChaos
2个回答

0

我之前发布过一个类似的问题,这是我想到的解决方案:

本地化JavaScript消息和验证文本

这里的优点是您可以共享在常规 .net 页面中使用的资源。

您的方法看起来也不错。


0

这是我做的方式,以防有人觉得有用。

我不想在JS上放置任何剃刀片,因为由于CSP,我将JS文件与cshtml分开。

因此,我在共享的cshtml中添加了一个元素,其中包含数组的内容,数组的每个元素都是一个键/值对,名称和本地化字符串的返回值由Razor返回。

<meta name="resources" content="[
          ['name1', '@HttpUtility.JavaScriptStringEncode(Resources.name1)'],
          ['name2', '@HttpUtility.JavaScriptStringEncode(name2)']
     ]" />

然后在js文件中,我将其转换为字典:

let livstrResMap = document.querySelector("meta[name='resources']").getAttribute("content");
livstrResMap = livstrResMap.replace(/'/g, '"')
let lioJSN = JSON.parse(livstrResMap)
let mcvcodResources = new Map(lioJSN);

最后,我使用格式化助手定义此处来使用本地化字符串。
alert(mcvcodResources.get('name1'));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接