分享
 
 
 

ASP.NET设计控件净化网站语言

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

一、概述

考虑一下这种情形:你为一个Web网站写了一个应用程序,它的功能是接受用户的输入并将输入内容永久保存,例如保存到数据库,另外还要在网站上显示出用户输入的内容,例如论坛就是一个很典型的例子。

如果用户来源很杂,必须考虑如何防止用户提交和张贴攻击性(或者色情的、庸俗的)的内容。可能的解决方案包括:

⑴ 将用户群限制到一个封闭的用户团体,即要求用户使用程序功能之前必须先注册/登录。这样,由于每次提交的内容都可以追查到提交者,用户破坏网站规则的可能性就小了很多。如果有用户做出了不应该做的事,你就可以核实用户身份,予以相应的处理。

⑵ 在网站上发布用户提交的内容之前,先由管理员审阅。很多时候,由于人力资源有限,这个办法不一定行得通。

⑶ 禁止用户提交攻击性内容。这是最理想的解决办法,把问题解决在起源。但具体应该怎么实现呢?

本文介绍的方案以一个复合控件为基础,利用一个XML文件来定义攻击性词语。我们将用VB.NET编写这个复合控件,用普通的文本编辑器和命令行编译器(vbc)完成整个工程的构建。

在正式编写控件之前,首先我们来简单地回顾一下ASP.NET中控件的概念。本文出现的所有控件都是服务器控件,它们在服务器上运行,将HTML代码发送到客户端。要理解控件的分类,可以从控件是否嵌入到Web表单页面(因而采用按需编译方式)或预先编译的角度来观察。微软定义了下列ASP.NET服务器控件:HTML服务器控件,Web服务器控件,验证控件,用户控件。

前三种控件读者应该已经比较熟悉了,对于开发者来说,它们是最简单的控件类型,在ASP.NET中已经由微软为我们编写好。用户控件则有所不同。用户控件是“包装”成.ascx页面形式的.aspx页面,其他.aspx页面可以通过注册和实例化来调用用户控件的功能。这是一种被寄予厚望的服务器端控件,对于ASP/ASP.NET开发者来说,它代表着一大进步,特别地,现在编写控件的语言已经全面支持面向对象技术。

ASP.NET用户控件由一个或多个服务器控件、静态HTML元素构成,可以包含额外的代码,每个用户控件封装一组特定的功能。用户控件可以通过简单地扩展现有服务器控件(控件组)得到,例如,带有旋转功能的图形控件,在文本框中保存日期的日历控件。

二、开发复合控件

控件要检查用户提交的内容是否包含“攻击性”词语,攻击性词语由一个XML文件定义,XML文件的结构如下:

<?xml version="1.0"? encoding="GB2312">

<words>

<word>词语一</word>

<word>词语二</word>

</words>

本文的复合控件(Composite)包含三个ASP.NET服务器控件:一个Textbox控件,一个Label控件,还有一个Button控件。当用户点击Button控件,Composite检查用户提交的文本是否包含了XML文件中指定的词语(XML文件的默认名字是bad_words.xml,通过一个自定义属性定义),并抛出一个自定义事件。另外,Composite控件还将它的Label子控件的一个Text属性显露成顶级属性。

复合控件可以有选择地将子控件显露成属性,或者有选择地将子控件的属性和事件作为顶级属性和事件显露出来。当复合控件整合来自子控件的属性时,它通常只是简单地委托子控件执行操作,如下面的例子所示:

// 将操作委托给标签对象,标签对象是一个

// System.Web.UI.WebControls.Label的实例

Public Property Text() As String

Get

EnsureChildControls()

Return label.Text

End Get

Set

EnsureChildControls()

label.Text = value

End Set

End Property

我们需要一个文本输入框让用户输入内容,一个按钮来提交表单,还要一个向用户反馈信息的文本标签。下面我们来看看Web表单的代码,复合控件就是在这里实例化的:

【composite.aspx】

<%@ page language="vb" debug="false" trace="false" %>

<%@ Register TagPrefix="Custom" Namespace="CustomControls" Assembly = "CustomControls" %>

<html>

<script language="VB" runat=server>

Private Sub CheckText(sender As Object, e As CheckEventArgs)

If e.Match = false Then

Composite.Text = "<h2>发布内容请遵守本站规则!不得发布攻击性言辞!</h2>"

Else

Composite.Text = "你提交的内容已通过检查!"

End If

End Sub

</script>

<body>

<h1>语言净化控件实例</h1><br>

<form runat=server>

<Custom:Composite id = "Composite" OnCheck = "CheckText"

filename = "bad_words.xml" runat = server/></form></body>

</html>

上面的代码首先注册指定的复合控件。我们将把控件的代码编译成一个.dll文件,放入应用的bin目录,这是ASP.NET首先搜索的位置。在Web表单构成的用户界面中,我们实例化了自定义控件,同时指定了:

⑴ 当控件抛出OnCheck事件,执行一个本地的子过程CheckText。我们把复合控件的标签的文本通过一个公用属性显露出来,标签的内容由OnCheck事件句柄设置的另一个公用属性决定。

⑵ 定义攻击性词语的XML文件的名字。

⑶ 另外,我们还定义了一个由复合控件调用的CheckText子过程。

现在来看复合控件本身。复合控件有两个类,用两个独立的VB源文件实现,分别是composite.vb和checkevent.vb。

【composite.vb】

Imports System

Imports System.Web

Imports System.Web.UI

Imports System.Web.UI.WebControls

Imports System.Xml

Imports System.Collections

Namespace CustomControls

Public Class Composite

Inherits Control

Implements INamingContainer

Private _filename As String = "bad_words.xml"

Private label As Label

Private box1 As TextBox

Public Property filename() As String

Get

Return _filename

End Get

Set

_filename = value

End Set

End Property

' 以用户提交的文本内容为输入参数。如果用户提交的内容包含攻击性言辞,

' 则返回修改后的版本,

' 否则,直接返回原始的文本。

Public Function CheckString(InputString as String) as string

Dim alWordList As new ArrayList

dim xmlDocPath as string = mappathsecure("bad_words.xml")

dim xmlReader as XmlTextreader = new xmlTextReader(xmlDocPath)

dim element as string

dim output as string

dim asterisks as string = "*************************"

' 将定义攻击性言辞的xml文件内容读入到一个ArrayList

while (xmlReader.Read())

if xmlReader.NodeType=xmlNodeType.Text then

alWordList.Add(xmlReader.Value)

end if

end while

xmlReader.Close()

' 检查用户提交的文本内容,将攻击性言辞替换为适当数量的星号

For Each element in alWordList

InputString=InputString.Replace(element,

asterisks.substring(1, (element.length)))

Next

Return InputString

End Function

Public Property Text() As String

Get

' 该方法首先检查ChildControlsCreated属性的当前值。如果该值是false,

' 则调用CreateChildControls方法

EnsureChildControls()

Return label.Text

End Get

Set

EnsureChildControls()

label.Text = value

End Set

End Property

Public Event Check As CheckEventHandler

Protected Overridable Sub OnCheck(ce As CheckEventArgs)

RaiseEvent Check(Me, ce)

End Sub

'创建Composite控件的子控件

Protected Overrides Sub CreateChildControls()

Controls.Add(New LiteralControl("<h3>请在下面输入文字内容: "))

'文本输入框

Dim box1 As New Textbox()

box1.Text = ""

Controls.Add(box1)

Controls.Add(New LiteralControl("</h3>"))

'按钮

Dim button1 As New Button()

button1.Text = "提交"

Controls.Add(New LiteralControl("<br>"))

Controls.Add(button1)

' 将一个事件句柄加入新创建的按钮对象

AddHandler button1.Click, AddressOf Me.ButtonClicked

Controls.Add(New LiteralControl("<br><br>"))

label = New Label()

label.Height = Unit.Pixel(50)

label.Width = Unit.Pixel(500)

label.Text = ""

Controls.Add(label)

End Sub

Protected Overrides Sub OnPreRender(e As EventArgs)

CType(Controls(1), TextBox).Text = ""

End Sub

Private Sub ButtonClicked(sender As [Object], e As EventArgs)

OnCheck(New CheckEventArgs(CType(Controls(1), TextBox).Text,

CheckString(CType(Controls(1), TextBox).Text)))

End Sub

End Class

End Namespace

上面代码的主要任务是:

⑴ 首先导入必要的名称空间,声明当前类所属的名称空间。

⑵ 接下来定义Composite的主体。Composite从最基本的Control类继承,另外还要实现INamingContainer接口。INamingContainer接口允许Composite控件将事件转发到它的Button子控件。

⑶ 用CreateChildControls方法(而不是OnInit或构造函数)创建子控件。

⑷ Composite控件没有显露出Button子控件的Click事件。相反,它处理了Click事件,并抛出自定义事件Check。

⑸ Composite控件显露了下列公用属性:Text,即Label子控件的Text属性值;FileName,允许获取和设置定义攻击性词语的XML文件的名字

⑹ 主要的检查功能由CheckString方法实现,它的输入参数是一个文本字符串。CheckString方法从XML文件读取禁用的词语,放入一个数组列表(ArrayList),然后检查指定的字符串是否包含禁用的词语。所有“攻击性”的词语将被适当数量的“*”替代。

⑺ OnPreRender清除文本框子控件的文本。

⑻ 当用户点击按钮,ButtonClicked开始执行。ButtonClicked调用onCheck子过程,传入适当的参数(一个新建的CheckEventArgs对象,创建CheckEventArgs对象的参数是检查前和检查后的文本)。OnCheck随后触发一个事件,该事件将由.aspx页面中的代码处理。

【CheckEvent.vb】

' 包含定制事件数据类CheckEventArgs的代码.

' 另外还定义了Check事件的事件句柄

Imports System

Namespace CustomControls

Public Class CheckEventArgs

Inherits EventArgs

Private _match As Boolean = False

Public Sub New(string1 As String, string2 as String)

If string1=string2 Then

_match = True

End If

End Sub

Public ReadOnly Property Match() As Boolean

Get

Return _match

End Get

End Property

End Class

Public Delegate Sub CheckEventHandler(sender As Object, ce As CheckEventArgs)

End Namespace

CheckEventArgs的构造函数是两个字符串,根据字符串的值设置相应的匹配标记_match。另外,上面的代码还定义了CheckEventHandler事件句柄。

编写好上面的代码后,如果你没有安装IDE,用下面的命令执行编译即可:

vbc /t:library /out:./bin/CustomControls.dll /r:System.dll /r:System.web.dll

/r:System.drawing.dll /r:System.Data.dll /r:System.xml.dll *.vb

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有