web-dev-qa-db-fra.com

Utiliser des chaînes de ressources ASP.NET à partir de fichiers javascript

Comment pourrait-on obtenir des chaînes de ressources resx dans du code javascript stocké dans un fichier .js? 

Si votre javascript est dans un bloc de script dans le balisage, vous pouvez utiliser cette syntaxe:

<%$Resources:Resource, FieldName %>

et il analysera la valeur de la ressource au fur et à mesure qu'il affichera la page ... Malheureusement, cela ne sera analysé que si le javascript apparaît dans le corps de la page. Dans un fichier .js externe référencé dans une balise <script>, ces balises de serveur ne sont évidemment jamais analysées.

Je ne veux pas avoir à écrire un ScriptService pour renvoyer ces ressources ou quoi que ce soit du genre, car elles ne changent pas après le rendu de la page, il est donc inutile d’avoir une activité aussi active.

Une possibilité pourrait être d'écrire un gestionnaire ashx et de pointer les balises <script> sur celle-ci, mais je ne sais toujours pas comment lire les fichiers .js et analyser les balises de serveur de cette manière avant de transmettre le texte au client. Existe-t-il une ligne de code que je peux exécuter et qui effectuera cette tâche de la même manière que l'analyseur ASP.NET?

Ou quelqu'un a-t-il d'autres suggestions?

28
Grank

Il n'y a pas de support natif pour cela.

Il y a quelque temps, j'ai créé un JavaScriptResourceHandler capable de servir des ressources Serverside dans la page cliente via des objets, chaque propriété de l'objet représentant un identifiant de ressource de localisation et sa valeur. Vous pouvez vérifier cela et le télécharger à partir de ce blog:

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

Je l'utilise abondamment dans un certain nombre d'applications et cela fonctionne bien. Le principal avantage est que vous pouvez localiser vos ressources à un endroit (Resx ou, dans mon cas, un fournisseur de ressources personnalisé utilisant une base de données) plutôt que de devoir disposer de plusieurs schémas de localisation.

19
Rick Strahl

Voici ma solution pour l'instant. Je suis sûr que je devrai le rendre plus polyvalent à l'avenir ... mais jusqu'à présent, c'est bien.

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

Donc je peux faire

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

et puis mes scripts peuvent faire référence par exemple window.Resources.Foo.Bar et obtenez une chaîne.

34
Domenic

alors que "Common" est le nom du fichier de ressources et Msg1 est le nom du champ. Cela fonctionne aussi pour les changements de culture.

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

En un mot, faites en sorte que ASP.NET serve javascript plutôt que HTML pour une page spécifique. Propre si cela est fait en tant que IHttpHandler personnalisé, mais à la limite une page fera l'affaire, n'oubliez pas de:

1) Supprimez tous les éléments ASP.NET et faites-les ressembler à un fichier JS.

2) Définissez le type de contenu sur "text/javascript" dans le codebehind.

Une fois que vous avez un script comme celui-ci, vous pouvez créer une copie de vos ressources côté client, que d'autres scripts côté client peuvent référencer à partir de votre application.

2
Wyatt Barnett

Si vos ressources se trouvent dans une assemblée distincte, vous pouvez utiliser la variable ResourceSet au lieu du nom de fichier. Construire sur @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);
    }
}

L'inconvénient est que cela ne permet pas d'activer plus d'un fichier de ressources par action. De cette façon, @Domenics answer est plus générique et réutilisable.

Vous pouvez également envisager d'utiliser OutputCache, car la ressource ne changera pas beaucoup entre les demandes.

[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

Cet article traite de quelques scénarios et décrit une bonne solution un peu similaire à la réponse ci-dessus de Domenic. http://michael-sander.eu/index.php/2010/07/29/using-localized- ressources-en-fichiers-javascript-en-asp-projet-mvc/comment-page-1/# comment-219

0
Ovini

Dans l'application Brown Field sur laquelle je travaille, nous avons un xslt qui transforme le fichier resx en un fichier javascript dans le cadre du processus de construction. Cela fonctionne bien puisqu'il s'agit d'une application Web. Je ne sais pas si la question initiale est une application Web.

0
Rob Murdoch

Ajoutez la fonction dans la classe 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")%>";

ou utilisation directe:

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

Remarque: La langue est mon nom de ressource. Examen: Language.resx et Language.en-US.resx

0
VolkanCetinkaya

En général, je passe la chaîne de ressource en tant que paramètre à la fonction javascript que j'appelle, ce qui me permet de continuer à utiliser la syntaxe d'expression dans le code HTML.

0
Chris Shaffer

utilisez un champ masqué pour contenir la valeur de la chaîne de ressources, puis accédez à la valeur du champ en javascript , par exemple: "/>

var todayString = $ ("input [nom = TodayString] [type = caché]"). val ();

0
Mandoleen