看到這里你可能會問,asp.net程序本身就是動態網站,還要如何動?
我這里所謂的動起來,是指動態加載,動態更新。好吧可能你又要問了動態網站本來就是動態加載,動態更新的。asp.net的程序依附于IIS(當然不是唯一)運行的,有代碼的更新,只需要拷貝到對應的目錄下面。刷新界面就加載最新程序了。無需重啟IIS。
但是我這里所說的是動態加載腳本。這里的腳本是C#的類文件(*.cs)文件動態編譯加入內存運行實例。
可能有人要問,這個有什么必要????
如果程序有修改,修改-編譯-拷貝。就是最新程序,不會影響線上程序??墒悄阆胂耄绻且粋€很小的問題呢?如果因為不同的需求變更,很小的代碼修改就行。那有必要編譯代碼,上傳文件嘛?
又或者你現在身邊的電腦沒有編譯工具,但是需要需改程序的某些功能,在允許范圍內情況下,你該怎么辦?
也許你說這些都是無聊的。沒有必要,沒有使用場景~!、
好吧,我只能說你沒有遇到而已,你問問你身邊管理發布程序部署程序的人,他們的難處吧,每一次小小的bug更新,都要拷貝多個文件上傳至服務器是一件多么麻煩的事情。
好吧。不廢話了,我來來講講為什么我要寫這篇文章,我是遇到了什么情況吧。
這段時間,我給一個公司的門戶網站改版,前臺的展示頁面要求純靜態頁面。
純靜態頁面也就要求在后臺更新了網站內容以后,需要發布生成純靜態頁面放在網站目錄下用于訪問~!
我用到的技術就是,通過模板文件,生成內容頁,然后保存文件。
但是模板文件里面包含一些內容需要在C#代碼里面構建,然后替換模板文件內容。
C#里面構建的HTML里面或許標簽,或許CSS樣式。有問題需要更新,或是需求變更需要更新,這個都是常事。但是一旦有更新就去修改代碼,發布,是一件非常頭疼的事情,我之前就描述過了。
在之前的文章一步一步開發Game服務器(三)加載腳本和服務器熱更新(二)完整版介紹過如果加載腳本文件,可是之前的測試有一個問題沒有測試過在asp.net下運行。
問題在于讀取本程序加載的引用的程序集問題。
之前查詢引用程序集,的時候查找了引用的程序集下面引用的程序集,導致在IIS加載了一些無法加載的文件,
var asss = AppDomain.CurrentDomain.GetAssemblies(); foreach (var item in asss) { foreach (var item222 in item.GetModules(false)) { ddlNames.Add(item222.FullyQualifiedName); } }
需要改成這樣如下,需要查找引用程序集下引用的程序集
var asss = AppDomain.CurrentDomain.GetAssemblies(); foreach (var item in asss) { if (!item.ManifestModule.IsResource() && item.ManifestModule.FullyQualifiedName.EndsWith(".dll") || item.ManifestModule.FullyQualifiedName.EndsWith(".DLL")) { ddlNames.Add(item.ManifestModule.FullyQualifiedName); } }
我們創建一個IScript文件夾創建一個ICreateScript.cs 接口文件
namespace TestWebLoadScript.IScripts{ public interface ICreateScript : IBaseScript { void CreateHtml(Page page, string type); }}
之前的文章里面講述了,,就是我定義的腳本加載器,不知道你加載了那些類,由于是腳本類不知道類名和實例,所以通過接口控制,也可看作接口編程。
接下來我們創建一個Scripts 文件夾 然后創建 PC 文件 然后下面創建 Default文件夾
創建 Indexhtml.temp文件存放模板代碼
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>我是Default版本</title></head><body> <form id="form1"> <div> <%string%> </div> </form></body></html>
上面的<%string%> 是替換關鍵字
創建CreateIndexScript.cs 文件來實現html文件的創建
namespace TestWebLoadScript.Scripts.PC.Default{ public class CreateIndexScript : ICreateScript { string filePath = "C:/html/PC/index.html"; public void CreateHtml(System.Web.UI.Page page, string type) { if (type == "Default") { if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(filePath))) { System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(filePath)); } string htmlPath = page.Server.MapPath("/Scripts/PC/Default/Indexhtml.temp"); string htmlContext = System.IO.File.ReadAllText(htmlPath); using (System.IO.StreamWriter sw = System.IO.File.CreateText(filePath)) { sw.Write(htmlContext.Replace("<%string%>", "我是Default " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"))); } } } }}
創建一個index.aspx 頁面
namespace TestWebLoadScript{ public partial class index : System.Web.UI.Page { PRotected void Page_Load(object sender, EventArgs e) { string savePath = Server.MapPath("/") + System.Configuration.ConfigurationManager.AppSettings["scriptPath"].ToString(); Sz.Network.LoadScriptPool.LoadScriptManager.GetInstance.LoadCSharpFile(new string[] { savePath }); var scripts = Sz.Network.LoadScriptPool.LoadScriptManager.GetInstance.GetInstances<ICreateScript>(); string type = this.Request["type"]; foreach (var script in scripts) { script.CreateHtml(this, type); } } }}
這是我們目前的程序需求情況,生成index的HTML模板
這時候發布web程序。
可是突然需求該了,或者說是模板改變了,如果我們的生成HTML、模板的程序是寫死了在代碼里面的話,那么這時候我們肯定需要更改代碼,。然后編譯。,再次發布。根據數據生成最新模板頁面;
很麻煩是嘛。
但是我們做成了腳本生成后,
我們把這兩個文件復制,拷貝一次,修改一下,換成
QQ版本
當然需要修改一下腳本文件的命名空間
namespace TestWebLoadScript.Scripts.PC.QQ
生成了qq版本的靜態頁面了。
我們把同樣的代碼在復制一份,創建Mobile版本;
再次生成,就完成了各個版本的靜態頁生成。
看到這里不知道各位看官有什么需要吐槽的呢????歡迎留言~!
新聞熱點
疑難解答