zoukankan      html  css  js  c++  java
  • MVC模式下如何实现RegisterStartupScript等功能

    本文源于http://www.achtmaal.com/blog/asp-net-mvc-and-registerclientscriptinclude,非常感谢原文作者的智慧和分享

    RegisterStartupScript系列的向前台输出脚本的方法,是基于WebForm的,在MVC日益盛行的时代,它则无法正常工作了。但不论出于什么原因,也许你还会需要用到它,至少我有这样的需求。原文的作者提供了一个方法,我这里不作翻译,简单地描述一下工作原理。

    1. 每一个页面虽然不再是Page对象,用不了Register***功能,但是它仍然在一个HTTP Pipeline里面。
    2. 每一个页面请求的HttpContext.Current.Items仍然适用,它对每一个请求负责,我们将不同的Script存在里面,并在Http Pipeline的不同EventHandler中进行处理。
    3. HttpContext.Current.Reponse.Filter可以截获整个页面的流,可以将其中的内容进行改写。

    与原文不同,我的代码场景和他不同,所以我做了简化。

    1. HtmlScriptHelper提供给用户进行调用,目的是向HttpContext.Current.Items中添加Script,调用方法和以前一样。
    2. 在context.BeginRequest += Context_BeginRequest;处理程序中,向HttpContext.Current.Reponse.Filter中添加过滤器。

      1 public class HtmlScriptStream : MemoryStream
      2     {
      3         private Stream OutputStream { get; set; }
      4         private HttpContext HttpContext { get; set; }
      5         private bool closing;
      6 
      7         public HtmlScriptStream(Stream outputStream, HttpContext httpContext)
      8         {
      9             this.OutputStream = outputStream;
     10             this.HttpContext = httpContext;
     11         }
     12 
     13         public override void Close()
     14         {
     15             // Using a StreamReader to read this will cause Close to be called again
     16             if (this.closing)
     17             {
     18                 return;
     19             }
     20 
     21             this.closing = true;
     22             byte[] buffer = null;
     23             Dictionary<string, string> scripts = HtmlScriptHelper.GetStartupScripts();
     24             if (scripts.Count > 0 
     25                 && this.HttpContext.Response.ContentType == "text/html" 
     26                 && this.HttpContext.Server.GetLastError() == null)
     27             {
     28                 var html = this.ReadOriginalHtml();
     29                 if (!string.IsNullOrEmpty(html))
     30                 {
     31                     string startupScripts = string.Empty;
     32                     foreach (string script in scripts.Values)
     33                     {
     34                         startupScripts += (script + Environment.NewLine);
     35                     }
     36                     if (!string.IsNullOrEmpty(startupScripts))
     37                     {
     38                         int endBodyIndex = html.LastIndexOf("</body>");
     39                         if (endBodyIndex != -1)
     40                         {
     41                             html = html.Insert(endBodyIndex, startupScripts);
     42                         }
     43                     }
     44                 }
     45 
     46                 buffer = this.HttpContext.Response.ContentEncoding.GetBytes(html);
     47 
     48             }
     49             else
     50             {
     51                 this.Position = 0;
     52                 buffer = this.GetBuffer();
     53             }
     54 
     55             this.OutputStream.Write(buffer, 0, buffer.Length);
     56             base.Close();
     57         }
     58 
     59         private string ReadOriginalHtml()
     60         {
     61             var html = string.Empty;
     62             Position = 0;
     63             using (var reader = new StreamReader(this))
     64             {
     65                 html = reader.ReadToEnd();
     66             }
     67 
     68             return html;
     69         }
     70     }
     71 
     72     public class HtmlScriptHelper
     73     {
     74         private const string STARTUP_SCRIPTS = "STARTUP_SCRIPTS";
     75         public static bool IsStartupScriptRegistered(string key)
     76         {
     77             return GetStartupScripts().ContainsKey(key);
     78         }
     79 
     80         public static void RegisterStartupScript(string key, string script)
     81         {
     82             if (!IsStartupScriptRegistered(key))
     83             {
     84                 GetStartupScripts().Add(key, script);
     85             }
     86         }
     87 
     88         internal static Dictionary<string, string> GetStartupScripts()
     89         {
     90             Dictionary<string, string> scripts 
     91                 = HttpContext.Current.Items[STARTUP_SCRIPTS] as Dictionary<string, string>;
     92             if (scripts == null)
     93             {
     94                 scripts = new Dictionary<string, string>();
     95                 HttpContext.Current.Items[STARTUP_SCRIPTS] = scripts;
     96             }
     97 
     98             return scripts;
     99         }
    100     }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Web;
     5 using System.Web.UI;
     6 
     7 namespace ScriptHttpModule
     8 {
     9     public class MyFilter : IHttpModule
    10     {
    11         public void Dispose()
    12         {
    13      
    14         }
    15 
    16         public void Init(HttpApplication context)
    17         {
    18             context.BeginRequest += Context_BeginRequest;
    19             context.PreRequestHandlerExecute += Context_PreRequestHandlerExecute;
    20         }
    21 
    22         private void Context_BeginRequest(object sender, EventArgs e)
    23         {
    24             HttpContext httpContext = HttpContext.Current;
    25             string url = httpContext.Request.Url.AbsolutePath;
    26             if (!(url.EndsWith(".axd") || url.EndsWith(".ashx")
    27                 || url.EndsWith(".aspx") || url.EndsWith(".asmx")))
    28             {
    29                 httpContext.Response.Filter = new HtmlScriptStream(httpContext.Response.Filter, httpContext);
    30             }
    31         }
    32 
    33         private void Context_PreRequestHandlerExecute(object sender, EventArgs e)
    34         {
    35             HttpApplication application = (HttpApplication)sender;
    36             HttpContext context = application.Context;
    37             if (context != null)
    38             {
    39                 string sbScript1 = "<script type="text/javascript">alert('a1');</script>";
    40                 string sbScript2 = "<script type="text/javascript">alert('a2');</script>";
    41                 string sbScript3 = "<script type="text/javascript">alert('a3');</script>";
    42                 Page thisPage = context.CurrentHandler as Page;
    43 
    44                 if (thisPage != null)
    45                 {
    46                     Type t = thisPage.GetType();
    47 
    48                     if (!thisPage.ClientScript.IsStartupScriptRegistered(t, "script-1"))
    49                     {
    50                         thisPage.ClientScript.RegisterStartupScript(t, "script-1", sbScript1);
    51                     }
    52                 }
    53                 else
    54                 {
    55                     HtmlScriptHelper.RegisterStartupScript("script-1", sbScript1);
    56                     HtmlScriptHelper.RegisterStartupScript("script-1", sbScript2);
    57                     HtmlScriptHelper.RegisterStartupScript("script-2", sbScript3);
    58                 }
    59             }
    60         }
    61     }
    62 }

    下载附件:http://files.cnblogs.com/files/volnet/MvcHtmlScriptTest.rar

  • 相关阅读:
    VS2005中的WebApplication和WebSite
    CodeFile 与 CodeBehind 的区别
    vs2005默认浏览器(IE)灵异事件
    杭电OJ第4252题 A Famous City
    湘大OJ第1490题 Generating Random Numbers
    中南OJ 2012年8月月赛 B题 Barricade
    中南OJ 2012年8月月赛 H题 Happy watering
    杭电OJ第4245题 A Famous Music Composer
    中南OJ 2012年8月月赛 I题 Imagination
    杭电OJ第4256题 The Famous Clock
  • 原文地址:https://www.cnblogs.com/volnet/p/mvc-register-script.html
Copyright © 2011-2022 走看看