2009-04-27 4 views
1

Я хочу, чтобы HttpModule вводил javascripts, css-ссылки в элемент HEAD из некоторых простых данных конфигурации. Я не уверен, какое событие я должен зацепить?How2: какое событие зацепить HttpModule для размещения js-ссылок в элементе head

Curently Я использую
- context.PreRequestHandlerExecute для изменения MasterPage динамически
- Context.BeginRequest для SEO оптимализации

Существует некоторая помощь в HTTPModule Event Execution Order?

Спасибо за любой совет. Cheers, X.

ответ

1

Вот как я осуществил то, что вы делаете без HttpModule. Мне не понравилась идея httpmodule, потому что, если я забыл ее зарегистрировать, и она не была запущена, мое приложение не сработало бы, и это было бы не очевидной ошибкой. На странице абсолютно необходимо включить JS, поэтому я решил поместить его в базовый класс страницы проекта.

Я реализовал это много лет назад, и хотел, чтобы иметь возможность включать больше, чем просто скрипты, поддерживает CSS, мета-теги, и т.д .... Я забыл, почему я использовал Page.Header.Controls.Add вместо того, чтобы просто page.ClientScript.RegisterClientScriptInclude, но была причина.

using System; 
using System.Collections.Generic; 
using System.Web; 
using System.Web.UI; 

namespace YourNamespace 
{ 
    public class HeaderIncludesManager 
    { 
     private List<string> m_IncludedFiles = new List<string>(); 

     public void IncludeScript(string s) 
     { 
      IncludeScript(s, null); 
     } 

     public bool IsIncluded(string file) 
     { 
      return (m_IncludedFiles.Find(s => s.Equals(file, StringComparison.InvariantCultureIgnoreCase)) != null); 
     } 

     public void IncludeScript(string script, string condition) 
     { 
      Page page = HttpContext.Current.CurrentHandler as Page; 
      if (!IsIncluded(script) || page == null) 
       return; 

      string scriptFile = string.Format("/{0}/{1}?v={2}", MyConfig.JSDir, script, MyConfig.BuildNumber); 
      if (page.Header != null) 
      { 
       string scriptTag = String.Format("<script language=\"javascript\" type=\"text/javascript\" src=\"{0}\"></script>\n", scriptFile); 
       if (!String.IsNullOrEmpty(condition)) 
        scriptTag = String.Format("<!--[{0}]><script language=\"javascript\" type=\"text/javascript\" src=\"{1}\"></script><![endif]-->\n", condition, scriptFile); 

       page.Header.Controls.Add(new LiteralControl(scriptTag)); 
       m_IncludedFiles.Add(script); 
      } 
      else if (!page.ClientScript.IsClientScriptIncludeRegistered(GetType(), scriptFile)) 
      { 
       page.ClientScript.RegisterClientScriptInclude(GetType(), scriptFile, scriptFile); 
       m_IncludedFiles.Add(script); 
      } 
     } 

     public void IncludeCss(string css) 
     { 
      Page page = HttpContext.Current.CurrentHandler as Page; 
      if (!IsIncluded(css) || page == null) 
       return; 

      string cssfile = string.Format("/{0}/{1}?v={2}", MyConfig.CssDir, css, MyConfig.BuildNumber); 
      if (page.Header != null) 
      { 
       ((Page)HttpContext.Current.CurrentHandler).Header.Controls.Add(new LiteralControl(String.Format("<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />\n", cssfile)));      
       m_IncludedFiles.Add(css); 
      } 
     } 

     public void IncludeJQuery() 
     { 
      IncludeScript("jquery-1.2.3.min.js"); 
     } 

     public void IncludeJQueryUI() 
     { 
      IncludeJQuery(); 
      IncludeScript("jquery.ui.1.0.min.js"); 
      IncludeCss("jquery-theme.css"); 
     } 

     public void IncludeFlotScripts() 
     { 
      IncludeJQuery(); 
      IncludeScript("flot/jquery.flot.js"); 
      IncludeScript("flot/excanvas.pack.js", "if IE"); 
     } 
    } 

    public class MyPage : Page 
    { 
     public HeaderIncludesManager HeaderIncludes = new HeaderIncludesManager(); 
    } 

    public class MyControl : UserControl 
    { 
     public new MyPage Page 
     { 
      get 
      { 
       return (MyPage)base.Page; 
      } 
     } 
    } 

    public class SomeControlThatNeedsScripts : MyControl 
    { 
     protected override void OnLoad(EventArgs e) 
     { 
      Page.HeaderIncludes.IncludeJQueryUI(); 
      base.OnLoad(e); 
     } 
    } 
} 
+0

Что мне нравится в этой реализации, так это то, что он загружает скрипты, css только для определенных страниц. Что может быть лучше в случае скриптов, которые не используются повсеместно. Благодарю. –

+0

Кто-нибудь замечает код, чтобы определить, существует ли заголовок 'if (page.Header! = Null)'? Я хочу знать, в каком случае page.header имеет значение null? Надежда @ Чтобы помочь в комментариях. Благодарю. –

+1

Вопрос состоял в том, как это сделать с помощью httpmodule. – drogon

0

HttpHandler был бы лучшим выбором для такого типа функциональности. Вот пример, который перебирает файлы css и javascript; это не совсем то, что вы ищете, но вы должны получить движется в правильном направлении: http://www.codeproject.com/KB/aspnet/HttpCombine.aspx

+0

Спасибо за подсказку. Это интересная реализация. –

7
using System; 
using System.Web; 
using System.Web.UI; 

namespace YourNamespace 
{ 
    public class YourModule : IHttpModule 
    { 
     public void Init(HttpApplication context) 
     { 
      context.PreRequestHandlerExecute += Application_PreRequestHandlerExecute; 
     } 

     private void Application_PreRequestHandlerExecute(object sender, EventArgs e) 
     { 
      Page page = HttpContext.Current.CurrentHandler as Page; 
      if (page != null) 
      { 
       string script = "/js/jquery.1.3.2.min.js"; 
       if (page.Header != null) 
       { 
        string scriptTag = String.Format("<script language=\"javascript\" type=\"text/javascript\" src=\"{0}\"></script>\n", script); 
        page.Header.Controls.Add(new LiteralControl(scriptTag)); 
       } 
       else if (!page.ClientScript.IsClientScriptIncludeRegistered(page.GetType(), script)) 
        page.ClientScript.RegisterClientScriptInclude(page.GetType(), script, script); 
      } 
     } 

     public void Dispose() { } 
    } 
} 

ASP.Net Жизненный цикл: http://msdn.microsoft.com/en-us/library/ms178473.aspx

+0

Спасибо, например. Я использую аналогичную реализацию. Я был просто более озабочен использованием правильного события. Например. в моем случае я использую context.PreRequestHandlerExecute + = ContextPreRequestHandlerExecute; а затем page.PreLoad + = PagePreLoad; В PagePreLoad затем установите js-элемент и работаем очень хорошо. Но правильно? –

+0

Да, это правильное событие. Я не делал этого в HttpModule, но я делаю это в своем базовом классе. Я отправлю еще один ответ, чтобы показать вам, как я это сделал. –

+0

@ Я использую ваш код, но page.Header всегда имеет значение null, поэтому скрипт добавляется всегда в тело страницы не в заголовке. Masterpage имеет , поэтому должно быть хорошо. Вы знаете, почему? Спасибо – Riga