【问题标题】:Use ASP.NET Resource strings from within javascript files在 javascript 文件中使用 ASP.NET 资源字符串
【发布时间】:2010-10-30 18:12:10
【问题描述】:

如何将 resx 资源字符串转换为存储在 .js 文件中的 javascript 代码?

如果您的 javascript 在标记中的脚本块中,您可以使用以下语法:

<%$Resources:Resource, FieldName %>

它会在呈现页面时解析资源值...不幸的是,只有当 javascript 出现在页面正文中时才会解析。在

我不想编写 ScriptService 来返回这些资源或类似的东西,因为它们在页面呈现后不会改变,所以让某些东西处于活动状态是一种浪费。

一种可能性是编写一个 ashx 处理程序并将

或者有人有其他建议吗?

【问题讨论】:

    标签: asp.net javascript resources


    【解决方案1】:

    这是我现在的解决方案。我确信我需要在未来让它更加通用......但到目前为止这很好。

    using System.Collections;
    using System.Linq;
    using System.Resources;
    using System.Web.Mvc;
    using System.Web.Script.Serialization;
    
    public class ResourcesController : Controller
    {
        private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
    
        public ActionResult GetResourcesJavaScript(string resxFileName)
        {
            var resourceDictionary = new ResXResourceReader(Server.MapPath("~/App_GlobalResources/" + resxFileName + ".resx"))
                                .Cast<DictionaryEntry>()
                                .ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
            var json = Serializer.Serialize(resourceDictionary);
            var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.{0} = {1};", resxFileName, json);
    
            return JavaScript(javaScript);
        }
    
    }
    
    // In the RegisterRoutes method in Global.asax:
    routes.MapRoute("Resources", "resources/{resxFileName}.js", new { controller = "Resources", action = "GetResourcesJavaScript" });
    

    这样我就可以了

    <script src="/resources/Foo.js"></script>
    

    然后我的脚本可以引用例如window.Resources.Foo.Bar 并得到一个字符串。

    【讨论】:

    • 我使用 Framework 4,我的应用是 Web,我必须添加对 System.Windows.Forms.dll 的引用来解析“ResXResourceReader”方法。我无法进入“ResourcesController”,ResourcesController 类位于 App_GlobalResources 文件夹中。我将 resx 文件设置为 Build Action: Resource。我放了一个断点,什么也没有。
    • 序列化为 JSON 的类称为 JavaScriptSerializer,而不是 Serializer,它不是静态的。
    • 我正在尝试使用它,但我从未接触过控制器。我在动作中有一个断点,但它永远不会到达那里。再加上 这将被添加到 _layout.chtml 文件中?
    • 除了上述答案之外,我还必须向 web.config 添加一个处理程序,以便 IIS 不会在该地址查找静态文件:&lt;system.webServer&gt; &lt;handlers&gt; &lt;add name="ScriptsHandler" path="/resources/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" /&gt; &lt;/handlers&gt; &lt;/system.webServer&gt;
    【解决方案2】:

    对此没有本机支持。

    我前段时间构建了一个 JavaScriptResourceHandler,它可以通过对象将服务器端资源提供给客户端页面,其中对象上的每个属性都代表一个本地化资源 ID 及其值。您可以从这篇博文中查看并下载它:

    http://www.west-wind.com/Weblog/posts/698097.aspx

    我已经在许多应用程序中广泛使用它,并且效果很好。这样做的主要好处是您可以在一个地方本地化您的资源(Resx 或在我的情况下使用数据库的自定义 ResourceProvider),而不必有多个本地化方案。

    【讨论】:

    • 嗯,一个有趣的方法。可能对我有用。缺点是我必须有一个单独的资源文件,仅用于我想要推出的内容,否则发送无用的额外内容......而且我在共享点内,因此将 resx 作为文件读取并解析它可能有问题,我们拭目以待。感谢您的帖子!
    【解决方案3】:

    而“Common”是资源文件的名称,Msg1 是字段名称。这也适用于文化变革。

                Partial Javascript...:
                messages: 
                {
                    <%=txtRequiredField.UniqueID %>:{                       
                        required: "<%=Resources.Common.Msg1 %>",
                        maxlength: "Only 50 character allowed in required field."
                    }
                }
    

    【讨论】:

    • 谢谢!完美运行。 code alert("&lt;%=Resources.LocalizedText.ErrorMessage %&gt;");
    【解决方案4】:

    简而言之,让 ASP.NET 为特定页面提供 javascript 而不是 HTML。如果作为自定义 IHttpHandler 完成,则最干净,但在紧要关头,页面也可以,只需记住:

    1) 清除所有 ASP.NET 的东西,让它看起来像一个 JS 文件。

    2) 在代码隐藏中将 content-type 设置为“text/javascript”。

    一旦您有了这样的设置脚本,您就可以创建资源的客户端副本,其他客户端脚本可以从您的应用中引用。

    【讨论】:

      【解决方案5】:

      如果您将资源放在单独的程序集中,则可以使用 ResourceSet 代替文件名。以@Domenics 为基础的绝佳答案:

      public class ResourcesController : Controller
      {
          private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
      
          public ActionResult GetResourcesJavaScript()
          {
              // This avoids the file path dependency.
              ResourceSet resourceSet = MyResource.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
      
              // Create dictionary.
              var resourceDictionary = resourceSet
                              .Cast<DictionaryEntry>()
                              .ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
              var json = Serializer.Serialize(resourceDictionary);
              var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.resources = {1};", json);
      
              return JavaScript(javaScript);
          }
      }
      

      缺点是每个操作不会启用多个资源文件。这样@Domenics 的答案就更加通用和可重用了。

      您也可以考虑使用OutputCache,因为资源在请求之间不会发生太大变化。

      [OutputCache(Duration = 3600, Location = OutputCacheLocation.ServerAndClient)]
      public ActionResult GetResourcesJavaScript()
      { 
          // Logic here...
      }
      

      http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/improving-performance-with-output-caching-cs

      【讨论】:

      • 除了上述答案之外,我还必须向 web.config 添加一个处理程序,以便 IIS 不会在该地址查找静态文件:&lt;system.webServer&gt; &lt;handlers&gt; &lt;add name="ScriptsHandler" path="/resources/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" /&gt; &lt;/handlers&gt; &lt;/system.webServer&gt;
      • @user1191559 不需要,因为我发布的答案不使用 .js 后缀。它只是一个端点。
      • 嗨@smoksnes,看到你的答案没有包括脚本实现部分,大多数用户会使用 Domenics 实现(包括 .js),所以它应该会有所帮助!
      【解决方案6】:

      我通常将资源字符串作为参数传递给我正在调用的任何 javascript 函数,这样我就可以继续在 HTML 中使用表达式语法。

      【讨论】:

      • 这通常也是我的倾向,但在这种情况下,它是 RadMenu 的客户端项目单击处理程序,因此它会导致有 7 种情况的 switch 语句,所有情况都显示不同的“你当然?”字符串 :(
      【解决方案7】:

      我正在开发的棕色现场应用程序有一个 xslt,它可以将 resx 文件转换为 javascript 文件作为构建过程的一部分。这很好用,因为这是一个 Web 应用程序。我不确定最初的问题是否是网络应用程序。

      【讨论】:

        【解决方案8】:

        使用隐藏字段来保存资源字符串值,然后在 javascript 中访问该字段值 例如 : " />

        var todayString= $("input[name=TodayString][type=hidden]").val();

        【讨论】:

          【解决方案9】:

          在BasePage类中添加函数:

              protected string GetLanguageText(string _key)
              {
                  System.Resources.ResourceManager _resourceTemp = new System.Resources.ResourceManager("Resources.Language", System.Reflection.Assembly.Load("App_GlobalResources"));
                  return _resourceTemp.GetString(_key);
              }
          

          Javascript:

              var _resurceValue = "<%=GetLanguageText("UserName")%>";
          

          或直接使用:

              var _resurceValue = "<%= Resources.Language.UserName %>";
          

          注意: 语言是我的资源名称。考试:Language.resx 和 Language.en-US.resx

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多