本文源于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中添加过滤器。

 public class HtmlScriptStream : MemoryStream
{
private Stream OutputStream { get; set; }
private HttpContext HttpContext { get; set; }
private bool closing; public HtmlScriptStream(Stream outputStream, HttpContext httpContext)
{
this.OutputStream = outputStream;
this.HttpContext = httpContext;
} public override void Close()
{
// Using a StreamReader to read this will cause Close to be called again
if (this.closing)
{
return;
} this.closing = true;
byte[] buffer = null;
Dictionary<string, string> scripts = HtmlScriptHelper.GetStartupScripts();
if (scripts.Count >
&& this.HttpContext.Response.ContentType == "text/html"
&& this.HttpContext.Server.GetLastError() == null)
{
var html = this.ReadOriginalHtml();
if (!string.IsNullOrEmpty(html))
{
string startupScripts = string.Empty;
foreach (string script in scripts.Values)
{
startupScripts += (script + Environment.NewLine);
}
if (!string.IsNullOrEmpty(startupScripts))
{
int endBodyIndex = html.LastIndexOf("</body>");
if (endBodyIndex != -)
{
html = html.Insert(endBodyIndex, startupScripts);
}
}
} buffer = this.HttpContext.Response.ContentEncoding.GetBytes(html); }
else
{
this.Position = ;
buffer = this.GetBuffer();
} this.OutputStream.Write(buffer, , buffer.Length);
base.Close();
} private string ReadOriginalHtml()
{
var html = string.Empty;
Position = ;
using (var reader = new StreamReader(this))
{
html = reader.ReadToEnd();
} return html;
}
} public class HtmlScriptHelper
{
private const string STARTUP_SCRIPTS = "STARTUP_SCRIPTS";
public static bool IsStartupScriptRegistered(string key)
{
return GetStartupScripts().ContainsKey(key);
} public static void RegisterStartupScript(string key, string script)
{
if (!IsStartupScriptRegistered(key))
{
GetStartupScripts().Add(key, script);
}
} internal static Dictionary<string, string> GetStartupScripts()
{
Dictionary<string, string> scripts
= HttpContext.Current.Items[STARTUP_SCRIPTS] as Dictionary<string, string>;
if (scripts == null)
{
scripts = new Dictionary<string, string>();
HttpContext.Current.Items[STARTUP_SCRIPTS] = scripts;
} return scripts;
}
}
 using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI; namespace ScriptHttpModule
{
public class MyFilter : IHttpModule
{
public void Dispose()
{ } public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
context.PreRequestHandlerExecute += Context_PreRequestHandlerExecute;
} private void Context_BeginRequest(object sender, EventArgs e)
{
HttpContext httpContext = HttpContext.Current;
string url = httpContext.Request.Url.AbsolutePath;
if (!(url.EndsWith(".axd") || url.EndsWith(".ashx")
|| url.EndsWith(".aspx") || url.EndsWith(".asmx")))
{
httpContext.Response.Filter = new HtmlScriptStream(httpContext.Response.Filter, httpContext);
}
} private void Context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
if (context != null)
{
string sbScript1 = "<script type=\"text/javascript\">alert('a1');</script>";
string sbScript2 = "<script type=\"text/javascript\">alert('a2');</script>";
string sbScript3 = "<script type=\"text/javascript\">alert('a3');</script>";
Page thisPage = context.CurrentHandler as Page; if (thisPage != null)
{
Type t = thisPage.GetType(); if (!thisPage.ClientScript.IsStartupScriptRegistered(t, "script-1"))
{
thisPage.ClientScript.RegisterStartupScript(t, "script-1", sbScript1);
}
}
else
{
HtmlScriptHelper.RegisterStartupScript("script-1", sbScript1);
HtmlScriptHelper.RegisterStartupScript("script-1", sbScript2);
HtmlScriptHelper.RegisterStartupScript("script-2", sbScript3);
}
}
}
}
}

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

MVC模式下如何实现RegisterStartupScript等功能的更多相关文章

  1. MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  2. 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表

    提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...

  3. 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  4. MVC模式下My97DatePicker日期控件引用注意事项

    My97DatePicker日期控件之前在用webform模式开发的时候,只要 <script language="javascript" type="text/j ...

  5. 卡卡游戏引擎之MVC模式下的事件处理

    前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...

  6. Android:MVC模式(下)

    在上一篇文章中,我们将 View 类单独出来并完成了设计和编写.这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序. 模型(Model)就是程序中封装了数 ...

  7. 编码风格:Mvc模式下SSM环境,代码分层管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.分层策略 MVC模式与代码分层策略,MVC全名是ModelViewController即模型-视图-控制器,作为一种软件设计典范,用一种业 ...

  8. MVC模式下unity配置,报错“No connection string named '**Context' could be found in the application config file”

     写在前面: 第一次配置时好好的,后来第二次改到MVC模式,把依赖注入写成字典的单例模式时,由于新建的ORM(数据库映射模型EF),怎么弄都不用,一直报错"No connection str ...

  9. MVC模式下xml文件的解析

    第一次写blog,组织不当和出错的地方还请大家多担当哈. java操作xml文件的方式中用的较多的有四种,DOM.SAX.JDOM.DOM4J.除第一种外其余的三种我都有试过,这后三种方案中我选择用S ...

随机推荐

  1. C# winform key value型数据如何绑定ComBox (hashtable,keyvaluepair,dictionary )

    cbUserAgent是一个combox ArrayList list = new ArrayList(); Dictionary<string, string> useragents = ...

  2. 使用HttpClient 4.3.4 自动登录并抓取中国联通用户基本信息和账单数据,GET/POST/Cookie

    一.什么是HttpClient? HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 ...

  3. Hibernate控制台显示创建数据库表语句

    package cqvie.yjq.View; import org.hibernate.Session; import org.hibernate.Transaction; import org.h ...

  4. 关于meta标签

    一.Meta标签中的format-detection属性及含义 意为:格式检测 或许你会有这样的经历:当你在制作手机端的页面中,点击了没有加任何链接的格式的数字时,这时手机会进行自动拔号提示操作! 禁 ...

  5. OA及权限系统

    一直想找一款适合自己的权限管理后台,始终都没找到合适的,决定自己写一个 开发环境:vs2012 ,sql2008 语言:C# 前端:ligurui,jquery ORM框架:EF6.0 先来晒下我的数 ...

  6. cesium+ geoserverTerrainProvide+png展示3D高程图展示

    一.发布png到geoserver的imagepyramid // translate png to tif epsg:4326 File png = new File(pngPathStr); Bu ...

  7. call_user_function()方法的使用

    call_user_func ( callback $function [, mixed $parameter [, mixed $... ]] ) 调用第一个参数所提供的用户自定义的函数. 返回值: ...

  8. Quartz.Net与MVC结合定时任务

    1.首先,我们打开Visual Studio 2015,创建一个ASP.NET MVC的Web应用程序项目. 2.然后通过程序包管理器控制台来安装Quartz.Net组件. Quartz.Net一个最 ...

  9. 下载Orchard源码

    下载地址:http://orchardproject.net/download

  10. Ubuntu上安装Minecraft服务器

    Minecraft由于其独特的魅力吸引了很多玩家.不过游戏的乐趣只有在和朋友一起玩的时候才最有意思,所以很早以前我就想建设自己的服务器.但由于专业知识欠缺,没有实现. 最近接触了Linux服务器,所以 ...