2010-09-03 2 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(); 
    } 
} 

EDIT

Для обеспечения большей ясности , Я опубликовал свой класс ScriptManager. Чтобы извлечь файл сценария, я просто называю это так:

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

имя вы передаете в нем в полной мере, чувствителен к регистру имя ресурса (обработчик исключения получает список из них по телефону GetManifestResourceNames()).

Это дает вам скрипт как строку - вы можете вынести его в файл, ввести его на страницу (это то, что я делаю) или все, что вам нравится.

+0

Спасибо за ответ, я пытаюсь его. Что такое m_scriptCache? – opaera

+0

Я не могу понять, как это работает. Не могли бы вы привести пример? У меня этот WebResource указан в файле AssemblyInfo: 'TestResources.Assembly.CheckAnswer.js'. – opaera

+0

Я пытаюсь, но GetManifestResourceNames() возвращает пустую коллекцию. – opaera

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

Это вернет список всех имен ресурсов, которые были установлены как «Встроенный ресурс». Имя, как правило, является полностью квалифицированным пространством имен, куда вы помещаете этот JS-файл. Так что, если ваш проект называется My.Project, и вы храните файл MyScript.js внутри папки в вашем проекте под названием Resources, полное имя будет 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); 
    } 
} 

Вы можете придерживаться всего этого кода в событии Application_Start в вашем Global.asax. Вы не хотите, чтобы работать для каждого запроса


Теперь получить ссылку на вашу Ассамблею другого дела, есть много способов.Один из способов состоит в том, чтобы включить весь приведенный выше код в вашу Ассамблею, а затем убедитесь, что вы ссылаетесь на эту сборку из основного проекта WebApp в Visual Studio, а затем получаете ссылку на выполняемую в настоящее время Ассамблею.

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

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

Затем вызовите ResourceLoader.LoadResources() из вашего мероприятия Application_Start в вашем Global.asax.

Надеется, что это помогает

+0

Спасибо за ответ, я пытаюсь. У меня есть проект ClassLibrary, называемый TestResources.Assembly У меня есть один файл js с именем CheckAnswer.js в корне сборки. Какая будет первая строка вашего кода? Я пробовал: System.Reflection.Assembly myAssembly = TestResources.Assembly.CheckAnswer.js , но это не работает. Извините, но я новичок в этом виде кода. – opaera

+0

Попробуйте ... Сборка myAssembly = Assembly.GetExecutingAssembly(); - Stream stream = myAssembly.GetManifestResourceStream ("TestResources.Assembly.CheckAnswer.js "); - Примечание: этот код предполагает, что он запущен в проекте« TestResources.Assembly », иначе вызов Assembly.GetExecutingAssembly() не будет работать. –

+0

Спасибо, но я не хочу использовать ресурсы в сборке.Я хотел бы иметь сборку точно так же, как контейнер js-файлов.Я хочу загрузить js-файлы в свой проект WebSite. Любые идеи? – opaera

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 /", чтобы везде, где ваш веб-приложение находится, может быть, написать код для работы с этим динамически
  • Убедитесь, что папка/Scripts существует в вашем корне 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

+0

Да, вы можете использовать этот подход для нескольких файлов. Если вы не хотите помещать этот код в ту же Ассамблею, где есть ваши файлы, попробуйте заменить «Assembly.GetExecutingAssembly()» на «Assembly.LoadFile (@» C: \ WebApps \ MyApp \ bin \ TestResources.Assembly.dll «)» –

 Смежные вопросы

  • Нет связанных вопросов^_^