使用Response.Filter过滤非法词汇

一般信息发布网站,论坛等均具有实现非法词汇过滤功能,即当用户录入非法词汇时,进行替换,使其无法显示到页面上,针对此种功能,通常采用的时,在读取时,在读到非法词汇后,进行替换。这样做的好处是不用将非法词汇存入数据库,缺点是要在每次读取时都要进行替换。另一种解决方案是在输出时过滤掉非常词汇,优点是只要写一次就好了,可以过滤整站的非法词汇,缺点是,非法词汇仍然存入到了数据库中,呵呵,大家可以有针对性的选择,本例用的是后者,起因在于当初没有做此功能,后来需要添加,这时又不想改原来代码,所以就想了这个办法,主要是采用了HttpResponse.Filter属性来处理。具体代码如下:

首先自定义一个类,来作为非法词汇的过滤器


using System;
using System.Text;
using System.IO;
public class ResponseFilter : Stream
{
    #region properties

    Stream responseStream;
    long position;
    StringBuilder html = new StringBuilder();

    #endregion

    #region constructor

    public ResponseFilter(Stream inputStream)
    {
        responseStream = inputStream;
    }

    #endregion

    #region implemented abstract members

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void Close()
    {
        responseStream.Close();
    }

    public override void Flush()
    {
        responseStream.Flush();
    }

    public override long Length
    {
        get { return 0; }
    }

    public override long Position
    {
        get { return position; }
        set { position = value; }
    }

    public override long Seek(long offset, System.IO.SeekOrigin direction)
    {
        return responseStream.Seek(offset, direction);
    }

    public override void SetLength(long length)
    {
        responseStream.SetLength(length);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return responseStream.Read(buffer, offset, count);
    }

    #endregion

    #region write method

    public override void Write(byte[] buffer, int offset, int count)
    {
        string sBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

        //得到非法词汇列表,这个可以在数据库或Web.Config中读取出来
        string pattern = @"(非法词汇1|非法词汇2|非法词汇3)";
        string[] s = pattern.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);

        foreach (string s1 in s)
        {
            sBuffer = sBuffer.Replace(s1, "**");
        }

        byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(sBuffer);
        responseStream.Write(data, 0, data.Length);
    }

    #endregion
}


然后再Global.asax文件中,添加如下代码:

view plaincopy to clipboardprint?
<STRONG class=c>//这个适合多个页一次过处理  
</STRONG><STRONG class=k>public</STRONG> <STRONG class=k>void</STRONG> Application_BeginRequest()   
{  
    <STRONG class=k>string</STRONG> path = HttpContext.Current.Request.Path.ToLower();  
    <STRONG class=k>string</STRONG>[] paths = <STRONG class=k>new</STRONG> <STRONG class=k>string</STRONG>[]  
    {  
        <STRONG class=s>"/aa/"</STRONG>,<STRONG class=s>"/bb/"</STRONG>  
    };  
    <STRONG class=k>foreach</STRONG> (<STRONG class=k>string</STRONG> item <STRONG class=k>in</STRONG> paths)  
    {  
        <STRONG class=k>if</STRONG> (path.StartsWith(item))  
        {  
            Response.Filter = <STRONG class=k>new</STRONG> ResponseFilter(Response.Filter);  
            <STRONG class=k>break</STRONG>;  
        }  
    }  

//这个适合多个页一次过处理
public void Application_BeginRequest()
{
    string path = HttpContext.Current.Request.Path.ToLower();
    string[] paths = new string[]
    {
        "/aa/","/bb/"
    };
    foreach (string item in paths)
    {
        if (path.StartsWith(item))
        {
            Response.Filter = new ResponseFilter(Response.Filter);
            break;
        }
    }
}
或者重写某页的Render方法

view plaincopy to clipboardprint?
<STRONG class=k>protected</STRONG> <STRONG class=k>override</STRONG> <STRONG class=k>void</STRONG> Render(HtmlTextWriter writer)  
{  
    StringWriter strWriter = <STRONG class=k>new</STRONG> StringWriter();  
    <STRONG class=k>base</STRONG>.Render(<STRONG class=k>new</STRONG> HtmlTextWriter(strWriter));  
    <STRONG class=k>string</STRONG> html = strWriter.ToString();  
    html = Util.ReplaceInvalidKeyword(html);  
    writer.Write(html);  


 


作者:水木    
 
原文地址:https://www.cnblogs.com/hsapphire/p/1568995.html