天天看點

一個頁面标題和過濾輸出的解決方案

首先要提到一個東西:Response.Filter,這個filter可以讓你捕到最後的html輸出,之後,就是對輸出的html進行文本替換的問題了,當然了,為了能獲得每次請求的輸出,這裡請出了Global.asax,在Global.asax的Application_BeginRequest事件裡截取html,事件代碼很簡單,就一行代碼如下:

protected void Application_BeginRequest(object sender, EventArgs e)

        {

            HttpContext.Current.Response.Filter = new HttpResponseFilter(HttpContext.Current.Response.Filter,new ReplaceTextList());

        }

從以上的一行代碼裡看出,多了一個自定義的HttpResponseFilter類,這類主要實作的功能是,從原來的Filter接收後,然後替換文本,最後又傳回一個Filter,由于Response.Filter 是一個Stream類,是以新的類HttpResponseFilter繼承自Stream,然後複寫Write方法,所有的文本替換都在這Write方法裡處理了。

方法代碼主要表現為如下:

public override void Write(byte[] buffer, int offset, int count)

        {

            //讀出寫的文字

            byte[] data = new byte[count];

            Buffer.BlockCopy(buffer, offset, data, 0, count);

            string inputText = Encoding.UTF8.GetString(data);

            //開始替換

            if (replaceTextList != null && replaceTextList.Count > 0)

            {

                foreach (KeyValuePair values in replaceTextList)

                {

                    inputText = Regex.Replace(inputText, values.Key, values.Value, RegexOptions.Singleline);

                }

                replaceTextList.Clear();

            }

            replaceTextList = null;

            //将替換後的寫入response

            byte[] newdata = Encoding.UTF8.GetBytes(inputText);

            filterStream.Write(newdata, 0, newdata.Length);

        }

看說明就知道分三步走:讀取原來的,然後替換,最後寫回去,當然了,要注意你的網站編碼是UTF8還是GB2312,簡單改一下,這裡的重點是,我擴充了替換那一塊,我用了一個Dictionary,然後循環替換,當然支援正則,是以替換的原始文字和替換後的文字就對應上兩個string上了,為了可擴充與友善大夥,我定義了一個抽象類,先實作了三個正則用于截取标題,說明,和關鍵字,如果還要過濾其它文本.....

上面說到:為了可擴充與友善大夥,我定義了一個抽象類,先實作了三個正則用于截取标題,說明,和關鍵字。

這裡抽象類代碼如下:

public abstract class ReplaceTextListBase

    {

        ///

        /// 将被傳回的替換文本集合清單

        ///

        public Dictionary replaceTextList = new Dictionary();

        ///

        /// 擷取目前請求頁面的url資訊

        ///

        public Uri PageUrl { get { return HttpContext.Current.Request.Url; } }

        ///

        /// 擷取html的title的正則

        ///

        public string TitleRegex { get { return ".*"; } }

        public string TitleFormat(string titleText)

        {

            return "";

        }

        ///

        /// 擷取html的Description的正則

        ///

        public string DescriptionRegex { get { return "]+name=[\"\']description[^<>]*[/]>"; } }

        public string DescriptionFormat(string descriptionText)

        {

            return "";

        }

        ///

        /// 擷取html的Keyword的正則

        ///

        public string KeywordRegex { get { return "]+name=[\"\']keywords[^<>]*[/]>"; } }

        public string KeywordFormat(string keywordText)

        {

;        return "";

        }

        ///

        /// 複寫此方法,調用replaceTextList.add()方法後,return replaceTextList;

        ///

        ///

        public virtual Dictionary GetReplaceTextList()

        {

            return replaceTextList;

        }

    }

看完這抽象類後,發現一個虛方法GetReplaceTextList(), 重點就在了

現在看一下我的執行個體中的子類的實作

public class ReplaceTextList:ReplaceTextListBase

    {

        public override System.Collections.Generic.Dictionary GetReplaceTextList()

        {

            replaceTextList.Add(TitleRegex,TitleFormat("TitleRegex"));

            replaceTextList.Add(DescriptionRegex,DescriptionFormat("descriptionttest"));

            replaceTextList.Add(KeywordRegex,KeywordFormat("keywordadfdfdf"));

            return replaceTextList;

        }

    }

這個例子中的子類實作很簡單,就複寫了一個虛方法,然後最終頁面的輸出就是标題為:

TitleRegex,其它兩個一看就知了,當然還有如果要替換其它或過濾檔案,隻要寫多幾個add方法把要替換的文字給替換掉就行了,替換的文字可以結合資料庫.

其實,隻是我例子上的簡單,直接就定死了标題為TitleRegex

是以,其實在這裡才是真正給使用者自己擴充的地方

看到我的抽象類裡留下了一個PageUrl吧,其實這裡就是重點了,如何根據Url查出Title和description和keyword,這就是使用者自己的實作的了

當然這裡可以給出一些思路:

1.建資料庫表,然後對url主機頭進行分類管理,自己定義替換字元等

其實就一查詢,接下來自己愛怎麼弄就怎麼弄了。。。。