一年前当本人拿到一个名叫TWIG的PHP程序时立即被作者OOP编程思想所折服很难想像TWIG中所有的功能(行事历邮件个性化)均在一个PHP文件(indexphp)中执行完成这就得益于作者采用了程序代码与页面构架分离的思想但是我也看到尽管作者做了很大的努力但由于PHP的局限性程序并没有真正做到代码与构架的分离indexphp这个主文件由于要执行的功能太多所以其require的模块文件相当之多至使整个文件依然显得十分零乱本人愚昧当时花了半个月的时间才真正明白程序的构架分析代码之苦无人能知啊(黯然泪下)
TWIG程序对我此后的编程有着很大的影响但是即使这样的作品依然没有摆脱程序代码与HTML代码混杂的局面
程序代码与页面构架的分离是WEB程序员多年的梦想在ASPNet出现之前无论是ASPPHP还是JSP程序代码与HTML代码都是混杂在一起的这种做法虽然在WEB技术初期受到赞扬但是随着时间的的推移它的弊端是越来越明显当程序代码很长时HTML代码与其混杂程序的可读性变得很差让人无法分清程序真正要表示的页面构架
而新技术ASPNet则通过Codebehind用户控件(User Control)以及自定义控件(Custom Control)等方法真正做到了代码的分离这是一个了不起的进步大家可以在本文中看到分离代码后的ASPNet程序的结构是多么的清晰
飞刀借此地向大家演示一下它们的具体实现方法我们先看看要实现的功能
为了便于理解这里设计的页面比较简单页面分为三个主要的部分头部包含一个AdRotator控件(用于显示广告)与一个Label控件(用于显示当前广告链接地址)中部是一个登陆页面包括两个TextBox控件(分别用于输入用户名与密码)一个Label控件(显示登陆是否成功)与一个Button控件(作为提交按钮)底部包含两个Label控件(分别显示当前用户名与用户权限)
熟悉ASPNet的朋友马上就会意识到头部由于使用了AdRotator控件所以必定存在OnAdCreated事件以便在Label控件显示相应链接而中部由于使用Button控件做为提交按钮所以必定有一个OnClick事件处理
CodeBehind
首先我们就看看如何使用CodeBehind方法来实现代码与页面构架的分离下面给出的源程序是主ASPNet程序Exampleaspx
<% @ Page Src=cs\EventHandlecs Inherits=Aspcn %>
<html>
<head>
<title></title>
</head>
<body>
<form runat=server>
<asp:Panel id=Header runat=server>
<asp:AdRotator id=ad AdvertisementFile=AdBanners\adxml BorderWidth= OnAdCreated=AdCreated runat=server /><br>
当前广告链接<asp:Label id=lblAdText ForeColor=red runat=server />
</asp:Panel>
<asp:Panel id=Logon runat=server>
<table>
<tr><td colspan= align=center><b>登陆窗口</b></td></tr>
<tr><td colspan= align=center><asp:Label id=lblMsgShow ForeColor=red runat=server /></td></tr>
<tr><td>用户名</td><td><asp:TextBox id=tbUserName runat=server /></td></tr>
<tr><td>密码</td><td><asp:TextBox id=tbPasswd TextMode=Password runat=server /></td></tr>
<tr><td><asp:Button id=btnSubmit Text=登陆 OnClick=Submit_Click runat=server /></td></tr>
</table>
</asp:Panel>
<asp:Panel id=Footer runat=server>
用户名<asp:Label id=lblUserName FontName=Arial ForeColor=red Text=游客 runat=server />
权限<asp:Label id=lblPurview FontName=Arial Text=无 ForeColor=red runat=server />
</asp:Panel>
</form>
</body>
</html>
例程中大家可以清楚地看到程序中不包含任何C#VBJavaScript来处理OnAdCreated与OnClick事件但是执行本程序程序能够正常使用(如图与图)这便是使用CodeBehinde的结果事件处理已经被转移到其它程序中定义执行请大家注意本例中第一行的信息
<% @ Page Src=cs\EventHandlecs Inherits=Aspcn %>
一般在ASPNet程序中Page指令都在设定本程序应当使用什么语言(使用Language属性)而本例中没有出现Language属性而是出现了两个新的Page属性Src与InheritsSrc属性设定事件处理真正的代码位置Inherits属性则设定需要引入的类名可以看到本例中定义事件处理的文件是EventHandlecs我们来看看它的具体内容
using System;
using SystemData;
using SystemDataSqlClient;
using SystemWeb;
using SystemWebUI;
using SystemWebUIWebControls;
using SystemWebUIHtmlControls;
public class Aspcn : Page
{
//声明Web Form中出现的控件
public Label lblAdTextlblUserNamelblPurviewlblMsgShow;
public TextBox tbUserNametbPasswd;
public Button btnSubmit;
public AdRotator ad;
private string strConnString = server=(local)\\Feidao;database=aspcn;Trusted_Connection=yes;
//处理Adrotator控件建立事件
public void AdCreated(Object srcAdCreatedEventArgs e)
{
lblAdTextText = eAlternateText;
}
public void Submit_Click(Object senderEventArgs e)
{
SqlConnection MyConn = new SqlConnection(strConnString);
MyConnOpen();
string strUserNamestrPasswordstrSelect;
strUserName = tbUserNameText;
strPassword = tbPasswdText;
strSelect = select * from bbs_user where id=+strUserName+ and password=+strPassword+;
SqlCommand MyComm = new SqlCommand(strSelectMyConn);
SqlDataReader dr = MyCommExecuteReader();
if(drRead())
{
//登陆成功
lblMsgShowText = 登陆成功;
lblUserNameText = dr[id]ToString();
lblPurviewText = dr[purview]ToString();
}
else
{
//登陆不成功
lblMsgShowText = 登陆不成功;
}
drClose();
MyConnClose();
}
}
进行事件处理是定义在一个类中的(本例中是Aspcn注意大小写)由于需要与Web Forms相关联所以此类还必须继承Page类
分析程序大家可以看到程序中对事件的处理操作是与普通的未进行代码分离的程序是一样的并没有什么特别的地方(本人在程序中已经给出的相关注释相信对大家理解程序有所帮助)
使用CodeBehind技术后大家需要多写一些代码比如声明控件等也许大家很不喜欢多写这样的代码但是大家也必须看到使用了CodeBehind技术后主程序的可读性大大增加了在Exampleaspx中相信大家很快就可以区分页面构架的各个部分大家想想这些构架如果在其它技术是否能看得如此清楚?
用户控件(UserControl)
CodeBehind技术真正实现了代码与构架的分离比以前的技术前进了一大步但是它的缺陷也是显而易见的比如主页面中部那个登陆区如果内容很多HTML显示代码的依然会占用很大的区域程序的可读性依然会降低
ASPNet也提供了解决办法这就是用户控件
用户控件我们可以将其视为不用编译的Server控件即然是控件那么就肯定会遵从控件的使用方法我们将Exampleaspx中的每个Panel整体看成为一个控件因此Exampleaspx的主体部分通过使用用户控件便可以减少为只有三行
<% @ Register TagPrefix=aspcn TagName=Header Src=UserControls/Headerascx %>
<% @ Register TagPrefix=aspcn TagName=Logon Src=UserControls/Logonascx %>
<% @ Register TagPrefix=aspcn TagName=Footer Src=UserControls/Footerascx %>
<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>
执行这个程序其运行结果与使用CodeBehind技术的结果是一样的但是现在的ASPNet程序更加容易区分页面构架了
<aspcn:Header id=MyHeader runat=server />
<aspcn:Logon id=MyLogon runat=server />
<aspcn:Footer id=MyFooter runat=server />
这三行代码使用了三个用户控件这么少的代码大家一眼就可以清楚的看到页面被分为三个部分
要使用用户控件就必须使用Register指令TagPrefix属性定义是的一个Namespace的名字以保证它在这个页面的唯一性;T