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 ...
随机推荐
- Window Server 2012 R2 没有照片查看器 打开图片都是画板问题怎么解决
新安装了 Window Server 2012 R2 系统,感觉屌屌的样子,加上开机速度蛮快,心里略爽.结果,打开图片一看,发现竟然是画板,而且还没有照片查看器,顿时泪流满面. 后来我利用了强大的百度 ...
- css3新特性@media(媒体查询)
现在web页面运行的设备的屏幕从pc端到pad,从pad到手机,各种各样,这样就用到了现在经常用到的响应式页面,为实现响应式页面开发,就用到一个非常有用的css3属性media(媒体查询). 介绍:媒 ...
- 使用AS编译jni文件无法编译出arm64-v8a,x86_64和mips64平台的.so文件的解决方法
我用的插件版本是:classpath 'com.android.tools.build:gradle-experimental:0.4.0',AS集成和使用ndk编译项目参考官方demo:https: ...
- NopCommerce 框架系列(二)
这一篇,让我们一起来认识一下 NopCommerce 的整体目录结构
- Linux基本权限学习
概念 权限就是用户对资源所能进行的操作 -- 这里涉及到三个重要的概念:用户.资源.操作. 首先,Linux中用户分为:u.g.o,就是用户.用户组.其他用户.--这里的用户是指拥有者!!!务必记住! ...
- Memcached Memcached.ClientLibrary.SockIOPool”的类型初始值设定项引发异常
又一次遭遇"xxx类型初始值设定项引发异常" 下了个c#实现的轻量级IoC开源项目,可是在本地使用时发现一运行就捕捉到"类型初始值设定项引发异常"的异常信息,调 ...
- javascript:history.go()和History.back()的区别(转载)
javascript:history.go()和History.back()的区别 <input type=button value=刷新 onclick="window. ...
- 如何用VB.Net创建一个三层的数据库应用程序
[b]1.[/b][b]概论:[/b] 本文将介绍如何创建一个三层应用程序,并且将介绍如何创建一个Web Service服务. ADO.NET创建Windows三层结构应用程序的体系架构如下图所示: ...
- CVTE实习面经
一个月的实习都结束了,我才把这篇面经放出来...可能有记得不太清楚的地方,还请多多见谅. 第一次面试是在5月中旬. 这次面试问的主要是基础的问题吧,就是C和C++的基础问题,我记得有问到下面几个问题 ...
- SQL Server Update 语句使用Nolock 语法
Update talblename set Column='XX' from Table TableName with(nolock) where XXX