TIPS-ASP.NET HTML偷天換日法
5 |
接連兩天,到了晚上十點多,我的部落格網站所有的ASPX就會傳回一片空白(謝謝chicken與ryan大德的通報)。由於程式是放在Hosting主機上,不可能Terminal Service連上去檢查,也沒法IISRESET,唯一能做的就是用FTP覆寫web.config重置Web Application,奇怪的是,總要覆寫個兩三次,問題才會排除。
接連的事故讓我有點危機感,想要建立一個備援網站,若是我親愛的讀者們一時無法看到我的文章而心生焦慮、感到沮喪、萬念俱灰、了無生趣的話,在下可就罪孹深重了。(謎之聲: 很好嘛~ 你再繼續往自己臉上貼金沒關係,知道恥字怎麼寫嗎?)
我還有另外一個Hosting http://blog2.darkthread.net ,把檔案複製過去就可以運作起來。但有一個問題,文章中很多地方我都寫死了http://Blog.darkthread.net ,包含了文章連結、檔案下載、圖檔位址等等,萬一主站掛了,連到blog2可以看到頁面,但圖檔出不來,文章連結失效,也不算成功的備援。
要如何解決這個問題? 我第一個想到的方法是用jQuery去找出所有的<a> <img>,將Blog.darkthread.net一律換成blog2.darkthread.net。但會有個問題,使用者會先看到被打X的圖檔,在document.onload事件後才一一重現,當主站掛點時,這個過程會格外地漫長。
於是,我想到的第二個方法---從ASPX端攔截,在ASP.NET產生好HTML要送出來之前,檢查全部的HTML內容,將所有出現的Blog.darkthread.net換成blog2.darkthread.net後再送出,但這要怎麼做呢?
在ASP.NET的處理過程中,要到Render階段,HTML內容才算定稿,所以最好的切入點應該是在Render()攔下要送出的HTML,偷改內容後再送出,就大功告成了。我的程式寫法如下:
protected override void Render(HtmlTextWriter writer)
{
//在備援網站上才要啟動
if (Request.Url.Host.ToLower() != "blog2.darkthread.net")
{
base.Render(writer);
return;
}
//自己做一個假的HtmlTextWriter去把HTML騙回來,草船借箭!!
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.StreamWriter sw = new System.IO.StreamWriter(ms);
HtmlTextWriter fakeHtmlTextWriter = new HtmlTextWriter(sw);
base.Render(fakeHtmlTextWriter);
sw.Flush();
string html = sw.Encoding.GetString(ms.ToArray());
//更動內容後,輸出到真正的HtmlTextWriter
writer.Write(html.Replace("b log.darkthread.net", "blog2.darkthread.net"));
}
雖然在Render裡做手腳會造成一些效能損耗,但我暫時也找不到其他更好的方法(有人有點子的話請出個聲),而這個Hack式的技巧,還可以解決一些刁鑽的需求,有其犀利之處,大家可以參考看看。
順便宣布,黑暗執行緒的備援網站在http://blog2.darkthread.net,即日起開始運作,萬一大家因主站當機掛點看不到文章而睡不著覺(謎之聲: 你夠了沒有?),可以暫時連至備援站台查資料。
Comments
# by Morris
哈哈! 接連兩三天, 連上貴站都有問題... 確實是有那麼點焦慮感產生了.... 會想說..慘了! 慘了! 我的密技法寶打不開了
# by Willy
我是訂閱RSS的方式檢視文章的~~ 所以也一直不知道有這樣的問題...但是真的掛了~~ 我的RSS也應該完蛋ㄌ吧~~(收不到新的文章...@@|||)
# by ben
請教一下, 您程式碼中的 base.Render(fakeHtmlTextWriter); 其中的 "base" 指的是什麼呢? 我想嘗試轉成 VB 但不成功吔 base 是 vb form 的 me 嗎? 還是?? 要如何轉至 VB 語系呢?
# by Jeffrey
To ben, Me == this, C# 的base應該是指VB.NET的MyBase
# by ben
感謝 Jeffery!! ^^