【问题标题】:How2: what event to hook in HttpModule for putting js links into head elementHow2:在 HttpModule 中挂接什么事件以将 js 链接放入 head 元素
【发布时间】:2009-04-27 09:38:21
【问题描述】:

我想让 HttpModule 从一些简单的配置数据中注入 javascripts、css 链接到 HEAD 元素。我不确定应该挂钩哪个事件?

目前我使用
- context.PreRequestHandlerExecute 用于动态更改母版页
- 用于 SEO 优化的 Context.BeginRequest

HTTPModule Event Execution Order? 有一些帮助

感谢任何提示。干杯,X。

【问题讨论】:

    标签: asp.net ihttpmodule


    【解决方案1】:
    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

    【讨论】:

    • 谢谢例如。我使用类似的实现。我只是对使用正确的事件更加好奇。例如。就我而言,我使用 context.PreRequestHandlerExecute += ContextPreRequestHandlerExecute;然后 page.PreLoad += PagePreLoad;然后在 PagePreLoad 中设置 js 元素并且效果很好。但对吗?
    • 是的,这是正确的事件。我没有在 HttpModule 中执行此操作,但我在我的基 Page 类中执行此操作。我将发布另一个答案,向您展示我是如何做到的。
    • @Chad,我正在使用您的代码,但 page.Header 始终为空,因此脚本始终添加到页面正文而不是标题中。母版页有一个 所以应该没问题。你知道这是为什么吗?谢谢
    【解决方案2】:

    这是我在没有 HttpModule 的情况下实现您正在做的事情的方法。我不喜欢 httpmodule 的想法,因为如果我忘记注册它并且它没有运行,我的应用程序将无法运行,这将是一个不明显的错误。该页面绝对需要包含 JS,所以我决定将它放在项目的基 Page 类中。

    我是在几年前实现的,希望能够包含的不仅仅是脚本,它还支持 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);
            }
        }
    }
    

    【讨论】:

    • 我喜欢这个实现的是它只为特定页面加载脚本、css。在脚本的情况下,这可能会更好,而脚本并不是在任何地方都使用。谢谢。
    • 有没有人注意到代码来确定标头是否存在if (page.Header != null)?我想知道在什么情况下 page.header 为 null ?希望@Chad 对 cme​​ts 有所帮助。谢谢。
    • 问题是如何使用 httpmodule 来做到这一点。
    【解决方案3】:

    对于此类功能,HttpHandler 将是更好的选择。这是一个结合 css 和 javascript 文件的示例;这不是您正在寻找的东西,但应该让您朝着正确的方向前进:http://www.codeproject.com/KB/aspnet/HttpCombine.aspx

    【讨论】:

    • 感谢提示。这是有趣的实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 2016-08-29
    • 2010-11-11
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多