MVC模式下如何實現RegisterStartupScript等功能
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中新增過濾器。
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 }
相關推薦
MVC模式下如何實現RegisterStartupScript等功能
RegisterStartupScript系列的向前臺輸出指令碼的方法,是基於WebForm的,在MVC日益盛行的時代,它則無法正常工作了。但不論出於什麼原因,也許你還會需要用到它,至少我有這樣的需求。原文的作者提供了一個方法,我這裡不作翻譯,簡單地描述一下工作原理。 每一個頁面雖然不再是Page物
在框架模式下實現分頁功能(原理)
目標:在Struts2框架中,使用分層架構方式實現分頁功能。 過程:Bean層->Dao層->Services層->Action層->Jsp頁面 具體實現: 1.Bean層 1)首先建立PageB
ATS 5.3.0在反向代理模式下實現正向代理功能方法
以前,我在records.config中一般是配置成正向+反向的形式: 現在我打算改為反向代理模式,但是需要實現正向代理的功能: 同時在remap.config中配置 regex_map http
asp.net網站MVC開發模式下實現Sitemap(站點導航)的一些經驗教訓
本來這是一個挺簡單的功能, MVC中雖然已經不再支援原先asp.net的siteMap控制元件,但是已經有開源的專案支援這一功能,那就是---MvcSiteMapProvider,藉助這個專案,我們只需簡單的幾個步驟就可以實現站點導航了。 第二步:解壓這個包,裡面有個sr
iOS·採用第三方(百度地圖SDK)實現定位等功能開發
陳滿iOS 關注 2017.05.01 01:06* 字數 2212 閱讀 6818評論 7喜歡 133 1.申請金鑰 首先,申請一個baidu賬號,接著進入新建金鑰入口申請成為baidu地圖開發者,填寫相關開發者資訊和簡訊驗證碼。接
VMware - NAT模式下實現區域網內物理機與虛擬機器的互通訪問
NAT模式:使用NAT模式,就是讓虛擬機器藉助NAT(網路地址轉換)功能,通過物理機來訪問網路。此模式下,如果物理機可以訪問網際網路,那麼虛擬機器也可以,預設情況下 和物理機同一網路中的其它機器不能訪問虛擬機器,但虛擬機器可以訪問其它物理機。 上面說預設情況下,物理機的其它機器不能訪問NAT模式
JAVA在不基於XML配置檔案的情況下實現郵件傳送功能(郵箱轟炸)
今天要講的是如何用Java程式碼實現簡單郵件傳送和複雜郵件傳送的功能,這裡我使用的是QQ郵箱,你們也可以嘗試使用其他的郵箱哦~ 想實現郵件傳送功能首先郵箱賬號必須要開啟 SMTP 服務,在網頁登入郵箱後點擊設定→賬戶然後下拉,如圖 &nb
C#在MVC模式下對單表專案執行總結的增刪改查
C#在MVC模式下對單表進行的增刪改查 1,首先建立一個新專案WebApplication1 2, 接著建立實體類product, 然後通過EF Code First建立資料庫初始資料。派生出DbContext的EF上下文。masterEntities對db檔案的實現 m
如何在ssm框架下實現攔截器功能,只用登入成功才能訪問其他網頁?
springmvc檔案 <!-- 配置攔截器 --> <mvc:interceptors> <mvc:interceptor> <!-- /**表示所有ur
移動端開發APPCAN呼叫高德地圖API實現定位等功能
最近專案在做移動端,做了點地圖應用,發現網上案例比較少,研究之後,給小夥伴們分享一份:看看程式碼吧,有不同的,call我嘍:<!doctype html><html><head> <meta charset="UTF-8">
Asp.NET MVC 使用 SignalR 實現推送功能二(Hubs 線上聊天室 獲取儲存使用者資訊)
簡單介紹 在上一篇中,我們只是介紹了簡單的訊息推送,今天我們來修改一下,實現儲存訊息,歷史訊息和使用者線上 使用者登入註冊資訊 當用戶登入之後,我們註冊一下使用者的資訊,我們在ChatHub中 新建一個方法 Register(使用者帳號,使用者密碼) 前臺js呼叫這個方法實現使用者註冊
Asp.NET MVC 使用 SignalR 實現推送功能一(Hubs 線上聊天室)
簡介 ASP .NET SignalR 是一個ASP .NET 下的類庫,可以在ASP .NET 的Web專案中實現實時通訊。什麼是實時通訊的Web呢?就是讓客戶端(Web頁面)和伺服器端可以互相通知訊息及呼叫方法,當然這是實時操作的。 WebSockets是HTML5提供的新的API
Thinkphp -- 利用MVC模式完成註冊登錄功能
跳轉 link url mar splay 更新時間 aps jquer white 這是一篇記錄向,記錄我後臺的學習過程。 如有不正確的地方,請多多指教。 基礎知識: MVC即 Model View Controller Model(模型)表示應用程序核心(比如數
編碼風格:Mvc模式下SSM環境,程式碼分層管理
本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent) # 一、分層策略 MVC模式與程式
整合springboot+mvc+mybatis(通用mapper)+druid+jsp+bootstrap實現許可權管理檔案上傳下載多資料來源切換操作日誌記錄等功能
花了兩週,學習了下springboot,然後做個小東西練練手.專案基於jdk1.8+maven整合了springboot+mvc+mybatis(通用mapper)+druid+jsp+bootstrap等技術,springboot+Listener(監聽器),Filter
JavaWeb,不使用框架下的MVC模式簡單登陸模組實現
專案結構圖 1. 前期準備 本專案使用的jdk版本是:jdk1.8.0_181 本專案使用的tomcat版本是:apache-tomcat-7.0.90 本專案使用的mysql資料庫版本是:mysql8.0 本專案使用的資料庫驅動是:my
如何在不使用系統函數的情況下實現PHP中數組系統函數的功能
如何 利用 數組 關聯 uniq 出現的次數 回調 數組賦值 fun PHP中為我們提供了各種各樣的系統函數來實現我們需要的各種功能,那麽,在不使用系統函數的情況下我們要怎樣來實現這些功能呢?以下就是幾種系統函數的實現方式。 首先,我們來定義一個數組: $arr= arr
【Web開發】Mean web開發 01-Express實現MVC模式開發
http scripts send javascrip 模板引擎 指令 開發環境 depend filter 簡介 Mean是JavaScript的全棧開發框架。更多介紹 用Express實現MVC模式開發是Mean Web全棧開發中的一部分。 Express 是一個基於
OSG立體模式下動態修改相機遠近裁剪面的實現
void base call struct clam ppr cti llc 源代碼 1. 非立體模式下動態修改相機遠近裁剪面 class GLB_DLLCLASS_EXPORT CGlbGlobeClipHandler : public osg::NodeCallbac
AngularJS實現數據列表的增加、刪除和上移下移等功能實例
enter 基礎 round 電子郵件 color bsp 基礎功 net 效果圖 轉: http://www.jb51.net/article/91991.htm 這篇文章給大家分享了AngularJS循環實現數據列表的增加、刪除和上移下移等基礎功能,對大家學習Ang