2010-09-03 40 views
4

我構建了一個包含一個js文件的程序集。 我將該文件標記爲Embedded Resource並將其添加到AssemblyInfo文件中。從嵌入資源的程序集中讀取

我不能從網站引用大會。它位於bin文件夾中,但我沒有看到它的引用。

它似乎沒有至少有一個類內部我不能引用它。

我會從程序集中將js文件包含到我的頁面中。

我該怎麼做?

謝謝

回答

2

我在我的一個項目中完全一樣的東西。我爲它拉他們,實際上緩存腳本中心的ScriptManager類,但是從嵌入式資源提取腳本文件的核心是這樣的:

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

編輯

爲客戶提供更清晰,我發佈了我的ScriptManager類。要提取一個腳本文件,我只是這樣稱呼它:

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

你把它傳遞名的完整,區分大小寫的資源名稱(異常處理程序通過調用GetManifestResourceNames()得到它們的列表)。

這給你腳本作爲一個字符串 - 然後你可以把它放到一個文件,注入到頁面(這是我在做什麼)或任何你喜歡的。

+0

感謝您的回答,我想它。 什麼是m_scriptCache? – opaera 2010-09-03 14:22:51

+0

我不知道如何使這個工作。你能舉個例子嗎?我在AssemblyInfo文件中指定了這個WebResource:'TestResources.Assembly.CheckAnswer.js'。 – opaera 2010-09-03 14:45:34

+0

我在嘗試,但GetManifestResourceNames()返回一個空的集合。 – opaera 2010-09-03 14:59:39

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

這將返回已被設置爲「嵌入式資源」的所有資源名稱的列表。該名稱通常是放置該JS文件的任何位置的完全限定名稱空間。所以,如果你的項目被稱爲My.Project和您存儲在您的項目稱爲Resources,一個文件夾內的MyScript.js文件的全名是My.Project.Resources.MyScript.js

然後,如果您想使用JS文件:

Stream stream = myAssembly.GetManifestResourceStream(myResourceName); 

在哪裏myResourceName參數可能是「My.Project.Resources.MyScript.js」。爲了獲得在流對象JS文件,你需要把它寫一個文件到硬盤,並從您的網站上投放它作爲一個靜態文件,像這樣:

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

和代碼對於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); 
    } 
} 

您可能希望將所有代碼都放在Global.asax的Application_Start事件中。您不希望它針對每個請求運行


現在獲取對您的組件的引用是另一回事,有很多方法。一種方法是將所有上述代碼包含在您的Assembly中,然後確保從Visual Studio中的主WebApp項目引用Assembly,然後像這樣獲取對當前正在執行的Assembly的引用。

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

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

然後從您的Global.asax中的Application_Start事件調用ResourceLoader.LoadResources()。

希望這有助於

+0

感謝您的回答,我正在嘗試。 我有我的ClassLibrary項目名爲TestResources.Assembly 我有一個名爲CheckAnswer.js在程序集的根目錄中的js文件。 代碼的第一行是什麼? 我試過了: System.Reflection.Assembly myAssembly = TestResources.Assembly.CheckAnswer.js 但它不起作用。 對不起,但我是新的這類代碼。 – opaera 2010-09-03 14:38:35

+0

Try ... Assembly myAssembly = Assembly.GetExecutingAssembly();流stream = myAssembly.GetManifestResourceStream(「TestResources。Assembly.CheckAnswer.js「);注意:這段代碼假設它在'TestResources.Assembly'項目中運行,否則對Assembly.GetExecutingAssembly()的調用將不起作用 – 2010-09-03 14:57:12

+0

謝謝,但我不想使用資源在程序集中我想讓程序集就像一個js文件的容器我想將js文件加載到我的WebSite項目中任何想法 – opaera 2010-09-03 15:02:57

0

工作的完整示例(我希望):

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

一些注意事項:

  • 更改 「C:/ webapps /下MyApp的/」 到哪裏你的Web應用程序位於,也許寫一些代碼,以動態解決這個問題
  • 確保/腳本文件夾存在於您的webapp根目錄
  • 我認爲這將覆蓋「MyScript.js」文件,如果它已經存在,但以防萬一,你可能要添加一些代碼來檢查該文件並刪除它

然後堅持調用此代碼在Global.asax文件:

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

然後爲你的網站的路徑將是/Scripts/MyScript.js例如:

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

我明白了,但通過這種方式,我將文件放入我的網絡應用程序,就像我將原始CheckAnswer.js包含到我的應用程序中一樣。 我想引用js文件,就像它們位於不同的域中一樣,但不是從此讀取它們大會,我讀了一些關於WebResource的事情,但我不能讓它工作。您的方法可能對組合多個文件有用,是嗎? – opaera 2010-09-03 15:35:08

+0

是的,你可以使用這種方法來處理多個文件。如果您不想將此代碼放入包含您的文件的相同程序集中,請嘗試將'Assembly.GetExecutingAssembly()'替換爲'Assembly.LoadFile(@「C:\ WebApps \ MyApp \ bin \ TestResources.Assembly.dll 「)」 – 2010-09-03 15:38:41