MVC模式下如何实现RegisterStartupScript等功能
本文源于http://www.achtmaal.com/blog/asp-net-mvc-and-registerclientscriptinclude,非常感谢原文作者的智慧和分享
RegisterStartupScript系列的向前台输出脚本的方法,是基于WebForm的,在MVC日益盛行的时代,它则无法正常工作了。但不论出于什么原因,也许你还会需要用到它,至少我有这样的需求。原文的作者提供了一个方法,我这里不作翻译,简单地描述一下工作原理。
- 每一个页面虽然不再是Page对象,用不了Register***功能,但是它仍然在一个HTTP Pipeline里面。
- 每一个页面请求的HttpContext.Current.Items仍然适用,它对每一个请求负责,我们将不同的Script存在里面,并在Http Pipeline的不同EventHandler中进行处理。
- HttpContext.Current.Reponse.Filter可以截获整个页面的流,可以将其中的内容进行改写。
与原文不同,我的代码场景和他不同,所以我做了简化。
- HtmlScriptHelper提供给用户进行调用,目的是向HttpContext.Current.Items中添加Script,调用方法和以前一样。
在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等功能的更多相关文章
- MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表
提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...
- 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- MVC模式下My97DatePicker日期控件引用注意事项
My97DatePicker日期控件之前在用webform模式开发的时候,只要 <script language="javascript" type="text/j ...
- 卡卡游戏引擎之MVC模式下的事件处理
前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...
- Android:MVC模式(下)
在上一篇文章中,我们将 View 类单独出来并完成了设计和编写.这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序. 模型(Model)就是程序中封装了数 ...
- 编码风格:Mvc模式下SSM环境,代码分层管理
本文源码:GitHub·点这里 || GitEE·点这里 一.分层策略 MVC模式与代码分层策略,MVC全名是ModelViewController即模型-视图-控制器,作为一种软件设计典范,用一种业 ...
- MVC模式下unity配置,报错“No connection string named '**Context' could be found in the application config file”
写在前面: 第一次配置时好好的,后来第二次改到MVC模式,把依赖注入写成字典的单例模式时,由于新建的ORM(数据库映射模型EF),怎么弄都不用,一直报错"No connection str ...
- MVC模式下xml文件的解析
第一次写blog,组织不当和出错的地方还请大家多担当哈. java操作xml文件的方式中用的较多的有四种,DOM.SAX.JDOM.DOM4J.除第一种外其余的三种我都有试过,这后三种方案中我选择用S ...
随机推荐
- CSS基础选择器
1.html负责结构,css负责样式,js负责行为. css是写在head标签里面,容器style标签里面, <style type="text/css"> body{ ...
- css之absolute绝对定位(绝对定位特性)
学习了绝对定位以后,对此进行一个总结,啦啦啦啦~ 绝对定位特性 1.破坏性 破坏了原有的位置,从文档流里脱离出来 2.包裹性 如果下面这种情况,父级元素将不会有高度和宽度,失去原有的大小
- C#中 字符串转换为计算公式
//方法一 利用DataTable中的Compute方法 例如:1*2-(4/1)+2*4=6 string formulate = string.Format("{0}*{1} - {2} ...
- 我 && yii2(日志埋点,邮件提醒)
今天试着把yii2 的日志,如果发送邮件的形式实现,具体实现如下 1.环境介绍 lnmp php5.6, mysql5.5, lnmp1.2 yii2-advanced 2.配置文件的编写 在fron ...
- sublime配置coffeeScript
node.js 全局模块所在目录 npm -g ls 1.安装 npm install -g coffee-script 2.sublime安装CoffeeScript sublime语法高亮插件 ...
- Linux SVN 命令详解(zz)
Linux下常用SVN命令 2012-04-02 11:46:00 标签:服务器 目录 Linux checkout linux系统 1.将文件checkout到本地目录 svn checkout p ...
- ASP.NET c# textbox 正则表达式 文本框只允许输入数字(验证控件RegularExpressionValidator )
<input type="text" name="test" onKeyUp="test1.value=(this.value=this.val ...
- android download manager
下载管理器,有个哥们写得很好了http://www.trinea.cn/android/android-downloadmanager/ 下载后台通知 下载管理器内容交互 最近对内部业务逻辑整理了一下 ...
- response.setHeader()的用法
一秒刷新页面一次 response.setHeader("refresh","1"); 二秒跳到其他页面 response.setHeader("re ...
- 异常:System.Data.EvaluateException: 未找到列[District].
异常:System.Data.EvaluateException: 未找到列[District]. 这里存在的问题不一定是说,数据源表没有该字段.此问题在于数据库字段包含空格字符.