問題遠沒結束
上面的問題解決了沒有?哦哦,我是指采取命名約定的方式來改變過濾行為。當然有問題 ,不過我這裡提一下比較重要的兩個:
首先,就是“改名”這種行為——究竟是否方便?還記得我們的需求嗎(提示一下:方便 、通用……)?如果采取上面的命名約定方案,我們可能就需要在頁面的前端和後端都不斷 地改名,一會兒加-noffw,一會兒加-json。如果項目只由您來負責這還好辦,只是麻煩一些 ,但是如果您的團隊中的前台開發人員性格古怪,固執己見,不願配合怎麼辦(打架我喜歡 ,可惜不能直接解決問題)?再者,假如您除了一個FilterForbiddenWordModule之外還有類 似的“FilterScriptInjectionModule”怎麼辦(別真寫這麼一個HttpModule,不合適,老趙 只是想不出一個恰當的例子了)?如果兩個Module都采取命名約定的方式,那麼如何制定一 個兩者能同時認同的約定就也是個麻煩事。
再者,命名真是我們可以控制的嗎?某些情況下好說,但是假如您在使用WebForms中的控 件怎麼辦?WebForm中的一個重要特性就是用過Naming Container來避免客戶端ID的沖突。假 設我們的頁面是放在一個Master Page中ID為Main的ContentPlaceHolder中,那麼ID為 txtPassword的文本框在客戶端裡生成的HTML便會如下所示——那麼我們又能有什麼辦法可以 做到“命名約定”嗎?
<input name="ctl00$Main$txtPassword" id="ctl00_Main_txtPassword"></input>
嘿,看來這種命名約定的方式有時候真不是那麼通用啊。那麼我就來設法解決WebForm這 個問題。
其實如果要解決WebForm這個問題,說白了就是要設法可以讓服務器端明確指定一些字段 的處理方式。這種“特殊”則意味著對於過濾方式的判斷必須與特定的Page——泛化一下, HttpHandler進行綁定。這裡我先談一下我的第一個想法:使用Custom Attribute進行標記的 方式。我們構造一個FilterForbiddenWordAttribute,其中包含一個抽象GetFilterType方法 根據key來指定過濾方式:
public enum FilterForbiddenWordType
{
Ignored,
Normal,
Json,
Html
}
public abstract class FilterForbiddenWordAttribute : Attribute
{
public abstract FilterForbiddenWordType GetFilterType(string key);
}
我們如果有特別的需求,就可以通過定義一個FilterForbiddenWordHandlerAttribute的 子類,重載GetFilterType方法,然後標記在HttpHandler上。如下:
public class DefaultFilterForbiddenWordAttribute :
FilterForbiddenWordAttribute
{
public override FilterForbiddenWordType GetFilterType(string key)
{
if (key.EndsWith("txtPassword"))
{
return FilterForbiddenWordType.Ignored;
}
return FilterForbiddenWordType.Normal;
}
}
[DefaultFilterForbiddenWord]
public partial class Default : System.Web.UI.Page
{
...
}