web-dev-qa-db-ja.com

JavaScriptファイル内からASP.NETリソース文字列を使用する

.jsファイルに保存されているJavaScriptコードにresxリソース文字列を取得するにはどうすればよいですか?

JavaScriptがマークアップのスクリプトブロック内にある場合は、次の構文を使用できます。

<%$Resources:Resource, FieldName %>

そして、ページをレンダリングするときにリソース値を解析します...残念ながら、それは、JavaScriptがページの本文に表示される場合にのみ解析されます。 <script>タグで参照される外部.jsファイルでは、これらのサーバータグは明らかに解析されません。

これらのリソースなどを返すためにScriptServiceを作成する必要はありません。ページがレンダリングされた後は変更されないので、アクティブなものを持つことは無駄です。

Ashxハンドラーを作成して<script>タグを指す可能性の1つはありますが、テキストをクライアントにストリーミングする前に、.jsファイルを読み取ってそのようなサーバータグを解析する方法がわかりません。 ASP.NETパーサーと同様にそのタスクを実行するコードを実行できますか?

または誰か他の提案がありますか?

28
Grank

これに対するネイティブサポートはありません。

先ほどJavaScriptResourceHandlerを作成しました。これは、オブジェクトを介してサーバーサイドのリソースをクライアントページに提供できるため、オブジェクトの各プロパティはローカリゼーションリソースIDとその値を表します。これをチェックして、このブログ投稿からダウンロードできます。

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

私はこれを多くのアプリで幅広く使用してきましたが、うまく機能します。これの主な利点は、複数のローカリゼーションスキームを用意する必要がなく、リソースを1か所(Resxまたは私の場合はデータベースを使用するカスタムResourceProvider)でローカライズできることです。

19
Rick Strahl

これが今のところ私の解決策です。将来はもっと用途を広げる必要があると確信しています...しかし、これまでのところこれで十分です。

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と文字列を取得します。

34
Domenic

一方、「Common」はリソースファイルの名前であり、Msg1はフィールド名です。これは文化の変化にも有効です。

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

簡単に言えば、ASP.NETが特定のページに対してHTMLではなくJavaScriptを提供するようにします。カスタムIHttpHandlerとして実行する場合は最もクリーンですが、ピンチでページが実行されます。

1)ASP.NETのものをすべて消去し、JSファイルのように見せます。

2)分離コードでcontent-typeを "text/javascript"に設定します。

この設定のようなスクリプトを作成したら、他のクライアント側スクリプトがアプリから参照できるリソースのクライアント側コピーを作成できます。

2
Wyatt Barnett

別のアセンブリにリソースがある場合は、ファイル名の代わりに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

2
smoksnes

この記事では、いくつかのシナリオについて説明し、上記のDomenicの回答に少し似た優れたソリューションについて説明します。 http://michael-sander.eu/index.php/2010/07/29/using-localized-resources-in-javascript-files-in-a-asp-mvc-project/comment-page- 1 /#comment-219

0
Ovini

私が取り組んでいるブラウンフィールドアプリケーションには、ビルドプロセスの一部としてresxファイルをjavascriptファイルに変換するxsltがあります。これはWebアプリケーションであるため、これはうまく機能します。元の質問がWebアプリケーションかどうかはわかりません。

0
Rob Murdoch

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

0
VolkanCetinkaya

通常、リソース文字列をパラメーターとして、呼び出しているjavascript関数に渡します。これにより、HTMLで式の構文を引き続き使用できます。

0
Chris Shaffer

非表示フィールドを使用してリソース文字列値を保持し、JavaScriptのフィールド値にアクセスします。例: "/>

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

0
Mandoleen