I want to have HttpModule to inject javascripts, css links into HEAD element from some simple config data. I am not sure which event I should hook?
Curently I use
- context.PreRequestHandlerExecute for changing the masterpage dynamically
- Context.BeginRequest for SEO optimalization
There is some help at http://stackoverflow.com/questions/441421/httpmodule-event-execution-order
Thanks for any tip. Cheers, X.
-
An HttpHandler would be a better choice for this type of functionality. Here is an example which goes over combining css and javascript files; it is not exactly what you are looking for but should get you headed in the right direction: http://www.codeproject.com/KB/aspnet/HttpCombine.aspx
Xabatcha : Thanks for tip.It is interesting implementation. -
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 Lifecycle: http://msdn.microsoft.com/en-us/library/ms178473.aspx
Xabatcha : Thanks for example. I use similar implementation. I was just more cirious about using right event. E.g. in my case I use context.PreRequestHandlerExecute += ContextPreRequestHandlerExecute; and then page.PreLoad += PagePreLoad; In PagePreLoad then set the js element and works very well. But is it right?Chad Grant : Yes, that is the correct event. I haven't done this in a HttpModule, but I do this in my base Page class. I'll post another answer to show you how I did it. -
Here's how I implemented what you are doing without a HttpModule. I didn't like the httpmodule idea because if I forgot to register it and it wasn't running, my app wouldn't work and it would have been a non obvious bug. The page absolutely needs the JS included so I decided to put it in the base Page class of the project.
I implemented this years ago, and wanted to be able to include more than just scripts, it supports css, meta tags, etc.... I forget why I used Page.Header.Controls.Add instead of just Page.ClientScript.RegisterClientScriptInclude but there was a reason.
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); } } }Xabatcha : What I like in this implementation is that it loads scripts,css only for specific pages. Which may be better in case of scripts, which are not used everywhere. Thanks.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.