1. 程式人生 > >MVC模式下如何實現RegisterStartupScript等功能

MVC模式下如何實現RegisterStartupScript等功能

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 }

相關推薦

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