2010-09-03 37 views
4

J'ai construit un assemblage contenant un fichier js. J'ai marqué le fichier en tant que ressource incorporée et l'a ajouté dans le fichier AssemblyInfo.Lecture à partir d'un assemblage avec des ressources incorporées

Je ne peux pas référencer l'assemblage à partir d'un site Web. C'est dans le dossier bin mais je ne vois pas la référence.

Il semble que je n'ai pas au moins une classe à l'intérieur de l'assemblage, je ne peux pas la référencer.

J'inclurais le fichier js dans mes pages depuis l'assemblage.

Comment est-ce que je devrais faire ceci?

Merci

Répondre

2

je fais exactement la même chose dans un de mes projets. J'ai une classe ScriptManager centrale qui met en cache en fait les scripts comme il les tire, mais le noyau d'extraire le fichier de script de la ressource incorporée ressemble à ceci:

internal static class ScriptManager 
{ 
    private static Dictionary<string, string> m_scriptCache = 
            new Dictionary<string, string>(); 

    public static string GetScript(string scriptName) 
    { 
     return GetScript(scriptName, true); 
    } 

    public static string GetScript(string scriptName, bool encloseInCdata) 
    { 
     StringBuilder script = new StringBuilder("\r\n"); 

     if (encloseInCdata) 
     { 
      script.Append("//<![CDATA[\r\n"); 

     } 

     if (!m_scriptCache.ContainsKey(scriptName)) 
     { 
      var asm = Assembly.GetExecutingAssembly(); 

      var stream = asm.GetManifestResourceStream(scriptName); 

      if (stream == null) 
      { 
       var names = asm.GetManifestResourceNames(); 
       // NOTE: you passed in an invalid name. 
       // Use the above line to determine what tyhe name should be 
       // most common is not setting the script file to be an embedded resource 
       if (Debugger.IsAttached) Debugger.Break(); 

       return string.Empty; 
      } 

      using (var reader = new StreamReader(stream)) 
      { 
       var text = reader.ReadToEnd(); 

       m_scriptCache.Add(scriptName, text); 
      } 
     } 

     script.Append(m_scriptCache[scriptName]); 

     if (encloseInCdata) 
     { 
      script.Append("//]]>\r\n"); 
     } 

     return script.ToString(); 
    } 
} 

EDIT

Pour fournir plus de clarté , J'ai posté ma classe ScriptManager. Pour extraire un fichier de script, je l'appelle simplement comme ceci:

var script = ScriptManager.GetScript("Fully.Qualified.Script.js"); 

Le nom que vous passez le nom complet de la ressource, sensible à la casse (le gestionnaire d'exceptions obtient une liste d'entre eux en appelant GetManifestResourceNames()). Cela vous donne le script sous forme de chaîne - vous pouvez ensuite le mettre dans un fichier, l'injecter dans la page (ce que je fais) ou ce que vous voulez.

+0

Merci pour la réponse, je l'essayer. Qu'est-ce que m_scriptCache? – opaera

+0

Je n'arrive pas à comprendre comment cela fonctionne. Pourriez-vous s'il vous plaît fournir un exemple? J'ai cette WebResource spécifiée dans le fichier AssemblyInfo: 'TestResources.Assembly.CheckAnswer.js'. – opaera

+0

J'essaye mais GetManifestResourceNames() retourne une collection vide. – opaera

0
Assembly myAssembly = // Get your assembly somehow (see below)... 
IList<string> resourceNames = myAssembly.GetManifestResourceNames(); 

Cela renverra une liste de tous les noms de ressources qui ont été définis comme 'Embedded Resource'. Le nom est généralement l'espace de nom complet de l'endroit où vous avez placé ce fichier JS. Donc, si votre projet est appelé My.Project et que vous stockez votre fichier MyScript.js dans un dossier dans votre projet appelé Resources, le nom complet serait My.Project.Resources.MyScript.js

Si vous souhaitez ensuite utiliser ce fichier JS:

Stream stream = myAssembly.GetManifestResourceStream(myResourceName); 

Où L'argument myResourceName peut être "My.Project.Resources.MyScript.js". Pour obtenir ce fichier JS dans cet objet Stream, vous aurez besoin de l'écrire dans un fichier sur le disque dur, et servez-le à partir de votre site Web comme un fichier statique, quelque chose comme ceci:

Stream stream = executingAssembly.GetManifestResourceStream(imageResourcePath); 
if (stream != null) 
{ 
    string directory = Path.GetDirectoryName("C:/WebApps/MyApp/Scripts/"); 

    using (Stream file = File.OpenWrite(directory + "MyScript.js")) 
    { 
     CopyStream(stream, file); 
    } 

    stream.Dispose(); 
} 

Et le code pour la méthode de CopyStream:

private static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8 * 1024]; 
    int len; 
    while ((len = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, len); 
    } 
} 

Vous pouvez coller tout ce code dans un événement Application_Start dans votre Global.asax. Vous ne voulez pas qu'il soit exécuté pour chaque requête


Maintenant, obtenir une référence à votre assembly est une question différente, il y a plusieurs façons.Une façon consiste à inclure tout le code ci-dessus dans votre assembly en question, puis assurez-vous de référencer cet assembly à partir de votre projet WebApp principal dans Visual Studio, puis obtenir une référence à l'assembly en cours d'exécution comme tel.

namespace My.Project 
{ 
    public class ResourceLoader 
    { 
     public static void LoadResources() 
     { 
      Assembly myAssembly = Assembly.GetExecutingAssembly(); 

      // rest of code from above (snip) 
     } 
    } 
} 

appellent ensuite ResourceLoader.LoadResources() de votre événement Application_Start dans votre Global.asax.

Hope this helps

+0

Merci pour la réponse, je l'essaie. J'ai mon projet ClassLibrary appelé TestResources.Assembly J'ai un fichier js appelé CheckAnswer.js à la racine de l'assembly. Quelle sera la première ligne de votre code? J'ai essayé: System.Reflection.Assembly myAssembly = TestResources.Assembly.CheckAnswer.js mais cela ne fonctionne pas. Désolé mais je suis nouveau dans ce genre de code. – opaera

+0

Essayez ... Assembly myAssembly = Assembly.GetExecutingAssembly(); - Flux de diffusion = myAssembly.GetManifestResourceStream ("TestResources.Assembly.CheckAnswer.js "); - Remarque: ce code suppose qu'il s'exécute dans le projet 'TestResources.Assembly' sinon l'appel à Assembly.GetExecutingAssembly() ne fonctionnera pas –

+0

Merci, mais je ne veux pas utiliser le Je souhaite que l'assemblage soit comme un conteneur de fichiers js. Je veux charger les fichiers js dans mon projet WebSite – opaera

0

exemple entièrement travail (je l'espère):

namespace TestResources.Assembly 
{ 
    public class ResourceLoader 
    { 
     public static void LoadResources() 
     { 
      Assembly myAssembly = Assembly.GetExecutingAssembly(); 

      Stream stream = myAssembly 
       .GetManifestResourceStream("TestResources.Assembly.CheckAnswer.js"); 

      if (stream != null) 
      { 
       string directory = Path.GetDirectoryName("C:/WebApps/MyApp/Scripts/"); 

       using (Stream file = File.OpenWrite(directory + "MyScript.js")) 
       { 
        CopyStream(stream, file); 
       } 

       stream.Dispose(); 
      } 
     } 

     private static void CopyStream(Stream input, Stream output) 
     { 
      byte[] buffer = new byte[8 * 1024]; 
      int len; 

      while ((len = input.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       output.Write(buffer, 0, len); 
      } 
     } 
    } 
} 

Quelques mises en garde:

  • Change "C:/webapps/MyApp /" à chaque fois que votre application web est situé, peut-être écrire du code pour le résoudre dynamiquement
  • Assurez-vous que le dossier/Scripts existe dans votre racine webapp
  • Je pense qu'il va remplacer le fichier « MyScript.js » si elle existe déjà, mais juste au cas où vous pouvez ajouter un peu de code pour vérifier ce fichier et supprimez-le

bâton Puis un appel à cette code dans votre fichier Global.asax:

protected void Application_Start() 
{ 
    ResourceLoader.LoadResources(); 
} 

Ensuite, le chemin pour votre site web sera /Scripts/MyScript.js par exemple:

<head> 
    <!-- Rest of head (snip) --> 
    <script type="text/javascript" src="/Scripts/MyScript.js"></script> 
</head> 
+0

Je vois, mais de cette façon, j'ai le fichier dans mon application web, tout comme j'inclus l'original CheckAnswer.js dans mon application Je voudrais référencer les fichiers js comme s'ils étaient dans un domaine différent, mais au lieu de les lire l'assemblée, j'ai lu chose à propos de WebResource mais je ne peux pas le faire fonctionner. Votre approche pourrait être utile pour combiner plusieurs fichiers, n'est-ce pas? – opaera

+0

Oui, vous pouvez utiliser cette approche pour plusieurs fichiers. Si vous ne voulez pas placer ce code dans le même assemblage contenant vos fichiers, remplacez 'Assembly.GetExecutingAssembly()' par 'Assembly.LoadFile (@ "C: \ WebApps \ MyApp \ bin \ TestResources.Assembly.dll ")" –