ASP.NET中程序构架与程序代码的分离 (2)
我们下面就要接触如何写SERVER控件。编写SERVER控件并不是一件轻松容易的事情,需要对.NET平台有比较深的了解,适合于高级用户,因此这里本人也不会具体描述SERVER控件的编写步骤(要细细讲这个,非得写书不可)。请大家比较一下自定义控件源代码与用户控件的区别,作一些大致的了解:
USING SYSTEM;
USING SYSTEM.DATA;
USING SYSTEM.DATA.SQLCLIENT;
USING SYSTEM.DRAWING;
USING SYSTEM.WEB;
USING SYSTEM.WEB.UI;
USING SYSTEM.WEB.UI.WEBCONTROLS;
NAMESPACE ASPCN
{
//首先是HEADER
PUBLIC CLASS HEADER:CONTROL,INAMINGCONTAINER
{
PRIVATE ADROTATOR AD;
PRIVATE LABEL LBLADTEXT;
PROTECTED OVERRIDE VOID CREATECHILDCONTROLS()
{
//加入ADROTATOR广告控件
AD = NEW ADROTATOR();
AD.ADVERTISEMENTFILE = "ADBANNERS/AD.XML";
AD.BORDERWIDTH = 0;
AD.ADCREATED += NEW ADCREATEDEVENTHANDLER(THIS.ONADCREATED);
THIS.CONTROLS.ADD(AD);
THIS.CONTROLS.ADD(NEW LITERALCONTROL("<BR>"+"当前广告链接为:"));
//加入LABEL控件
LBLADTEXT = NEW LABEL();
LBLADTEXT.FORECOLOR = COLOR.RED;
THIS.CONTROLS.ADD(LBLADTEXT);
}
PRIVATE VOID ONADCREATED(OBJECT SENDER,ADCREATEDEVENTARGS E)
{
THIS.LBLADTEXT.TEXT = E.ALTERNATETEXT;
}
}
//接着是LOGON
PUBLIC CLASS LOGON : CONTROL,INAMINGCONTAINER
{
PRIVATE STRING STRCONNSTRING = "SERVER=(LOCAL)\FEIDAO;DATABASE=ASPCN;TRUSTED_CONNECTION=YES";
PRIVATE LABEL LBLMSGSHOW;
PRIVATE TEXTBOX TBUSERNAME,TBPASSWD;
PUBLIC STRING USERNAME
{
GET
{
RETURN TBUSERNAME.TEXT;
}
SET
{
TBUSERNAME.TEXT = VALUE;
}
}
PROTECTED OVERRIDE VOID CREATECHILDCONTROLS()
{
//添加HTML标签
THIS.CONTROLS.ADD(NEW LITERALCONTROL("<TABLE><TR><TD COLSPAN="2" ALIGN="CENTER"><B>登陆窗口</B></TD></TR> <TR><TD COLSPAN="2" ALIGN="CENTER">"));
//添加MSGSHOW LABEL控件
LBLMSGSHOW = NEW LABEL();
LBLMSGSHOW.FORECOLOR = COLOR.RED;
THIS.CONTROLS.ADD(LBLMSGSHOW);
THIS.CONTROLS.ADD(NEW LITERALCONTROL("</TD></TR><TR><TD>用户名:</TD><TD>"));
//添加USERNAME与PASSWD TEXTBOX控件
TBUSERNAME = NEW TEXTBOX();
THIS.CONTROLS.ADD(TBUSERNAME);
THIS.CONTROLS.ADD(NEW LITERALCONTROL("</TD></TR><TR><TD>密码:</TD><TD>"));
TBPASSWD = NEW TEXTBOX();
TBPASSWD.TEXTMODE = TEXTBOXMODE.PASSWORD;
THIS.CONTROLS.ADD(TBPASSWD);
THIS.CONTROLS.ADD(NEW LITERALCONTROL("</TD></TR><TR><TD>"));
//添加BTNSUBMIT BUTTON控件
BUTTON BTNSUBMIT = NEW BUTTON();
BTNSUBMIT.TEXT = "登陆";
BTNSUBMIT.CLICK += NEW EVENTHANDLER(THIS.SUBMIT_CLICK);
THIS.CONTROLS.ADD(BTNSUBMIT);
THIS.CONTROLS.ADD(NEW LITERALCONTROL("</TD></TR></TABLE>"));
}
//显示完毕
PRIVATE VOID SUBMIT_CLICK(OBJECT SENDER,EVENTARGS E)
{
SQLCONNECTION MYCONN = NEW SQLCONNECTION(STRCONNSTRING);
MYCONN.OPEN();
STRING STRUSERNAME,STRPASSWORD,STRSELECT;
STRUSERNAME = TBUSERNAME.TEXT;
STRPASSWORD = TBPASSWD.TEXT;
STRSELECT = "SELECT * FROM BBS_USER WHERE ID='"+STRUSERNAME+"' AND PASSWORD='"+STRPASSWORD+"'";
SQLCOMMAND MYCOMM = NEW SQLCOMMAND(STRSELECT,MYCONN);
SQLDATAREADER DR = MYCOMM.EXECUTEREADER();
IF(DR.READ())
{
//登陆成功
THIS.LBLMSGSHOW.TEXT = "登陆成功";
}
ELSE
{
//登陆不成功
THIS.LBLMSGSHOW.TEXT = "登陆不成功";
}
DR.CLOSE();
MYCONN.CLOSE();
}
}
//最后是FOOTER
PUBLIC CLASS FOOTER : CONTROL,INAMINGCONTAINER
{
PRIVATE STRING _USERNAME,_PURVIEW;
PUBLIC STRING USERNAME
{
GET
{
RETURN _USERNAME;
}
SET
{
_USERNAME = VALUE;
}
}
PUBLIC STRING PURVIEW
{
GET
{
RETURN _PURVIEW;
}
SET
{
_PURVIEW = VALUE;
}
}
PUBLIC FOOTER()
{
_USERNAME = "游客";
_PURVIEW = "无";
}
PROTECTED OVERRIDE VOID CREATECHILDCONTROLS()
{
THIS.CONTROLS.ADD(NEW LITERALCONTROL("用户名:"));
LABEL LBLUSERNAME = NEW LABEL();
LBLUSERNAME.FORECOLOR = COLOR.RED;
LBLUSERNAME.FONT.NAME = "ARIAL";
LBLUSERNAME.TEXT = THIS.USERNAME;
THIS.CONTROLS.ADD(LBLUSERNAME);
//THIS.CONTROLS.ADD(NEW LITERALCONTROL("NBSP;"));
THIS.CONTROLS.ADD(NEW LITERALCONTROL("权限:"));
LABEL LBLPURVIEW = NEW LABEL();
LBLPURVIEW.FORECOLOR = COLOR.RED;
LBLPURVIEW.FONT.NAME = "ARIAL";
LBLPURVIEW.TEXT = THIS.PURVIEW;
THIS.CONTROLS.ADD(LBLPURVIEW);
}
}
}
上面和程序是将需要实现的功能,全部导入了自定义控件。程序中可以看到,在ASPCN命名空间中包含三个类(HEADER,LOGON,FOOTER),这三个类正是构架三个主体部分。
要使用自定义控件,还必须将原代码进行编译。
CSC /T:LIBRARY /OUT:ASPCN.DLL /R:SYSTEM.DATA.DLL,SYSTEM.WEB.DLL,SYSTEM.DRAWING.DLL CUSTOMCONTROLS.CS
C#程序编译指令的用法,本人在此也不再重复。需要注意的是编译的文件名,必须与控件中NAMESPACE的名字一致。
编译后的DLL,仍然不能使用,我们必须将其放到.NET平台中最著名的目录--/BIN中,BIN目录(如果不存在,可以自行建立)存放的是当前虚拟目录中所有使用自定义控件以及组件,CLR在执行ASP.NET程序时会自动搜索此目录中的文件,以找到与ASP.NET程序相匹配的NAMESPACE、CLASS 以及ASSEMBLY。
当我们将程序编译好的ASPCN.DLL放入/BIN目录后,这个自己编写的SERVER控件便可以使用了。
(需要声明一下,由于编写SERVER控件时不能使用SESSION等变量,以至无法做到两个CLASS之间的通信,因此在缺省状态下FOOTER控件并不能像前面的程序一样随SESSION内容发生改变,不过可以通过普通操作SERVER控件的方法来操作相应的属性达到相同的效果,此处为节约版面,未采用)
下面再来看看主体WEB FORM的程序内容:
<% @ REGISTER TAGPREFIX="ASPCN" NAMESPACE="ASPCN" ASSEMBLY="ASPCN" %>
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<FORM RUNAT="SERVER">
<ASPCN:HEADER ID="MYHEADER" RUNAT="SERVER" />
<ASPCN:LOGON ID="MYLOGON" RUNAT="SERVER" />
<ASPCN:FOOTER ID="MYFOOTER" RUNAT="SERVER" />
</FORM>
</BODY>
</HTML>
怎么样,相当简单明了吧。
引用我们自定义的控件,也相当简洁,只需将REGISTER指令的TAGPREFIX、NAMESPACE、ASSEMBLY属性全部设定为ASPCN。
至此,ASP.NET中三种代码与页面构架分离的方法已经介绍完毕。
三种方法各有优劣,本人比较倾向于使用用户控件与CODEBINDE技术结合使用,因为他们均不需要编译,相对来说更容易使用,如果您要保护你的代码,自定义控件则当然是您最佳的选择。
希望本文对您的编程有所帮助。

[
1]
[2] 