如果您希望看到关键字过滤算法的话那么可能就要失望了。博客园中已经有不少关于此类 算法的文章(例如这里和这里),虽然可能无法直接满足特定需求,但是已经足够作为参考 使用。而本文的目的,是给出一个较为完整的关键字过滤功能,也就是将用户输入中的敏感 字符进行替换——这两者有什么区别?那么就请继续看下去吧。:) 有趣的需求
关键字过滤功能自然无比重要,但是如果要在代码中对每个输入进行检查和替换则会是一 件非常费神费事的事情。尤其是如果网站已经有了一定规模,用户输入功能已经遍及各处, 而急需对所有输入进行关键字过滤时,上述做法更可谓“远水解不了近渴”。这时候,如果 有一个通用的办法,呼得一下为整站的输入加上了一道屏障,那该是一件多么惬意的事情。 这就是本文希望解决的问题。是不是很简单?我一开始也这么认为,不过事实上并非那么一 帆风顺,而且在某些特定条件下似乎更是没有太好的解决方法……
您慢坐,且听我慢慢道来……
实现似乎很简单
数据结构中的单向链表可谓无比经典。有人说:单向链表的题目好难啊,没法逆序查找, 很多东西都不容易做。有人却说:单向链表既然只能向一个方向遍历,那么变化就会很有限 ,所以题目不会过于复杂。老赵觉得后者的说法不无道理。例如在现在的问题上,我们如果 要在一个ASP.NET应用程序中做一个统一的“整站方案”,HttpModule似乎是唯一的选择。
思路如下:我们在Request Pipeline中最早的阶段(BeginRequest)将请求的 QueryString和Form集合中的值做过滤,则接下来的ASP.NET处理过程中一切都为“规范”的 文字了。说干就干,不就是替换两个NameValueCollection对象中的值吗?这再简单不过了:
public class FilterForbiddenWordModule : IHttpModule
{
void IHttpModule.Dispose() { }
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(OnBeginRequest);
}
private static void OnBeginRequest(object sender, EventArgs e)
{
var request = (sender as HttpApplication).Request;
ProcessCollection(request.QueryString);
ProcessCollection(request.Form);
}
private static void ProcessCollection(NameValueCollection collection)
{
var copy = new NameValueCollection();
foreach (string key in collection.AllKeys)
{
Array.ForEach(
collection.GetValues(key),
v => copy.Add(key, ForbiddenWord.Filter(v)));
}
collection.Clear();
collection.Add(copy);
}
}