TWIG程序对我此后的编程有着非常大的影响,但即便如此的作品,依旧没摆脱程序代码与HTML代码混杂的局面。
程序代码与页面构架的离别是WEB技术员多年的梦想。在ASP.Net出现之前,无论是ASP、PHP还是JSP,程序代码与HTML代码都是混杂在一块的,这种做法,虽然在WEB技术初期遭到赞扬,但伴随时间的的推移,它的弊病是愈加明显,当程序代码非常长时,HTML代码与其混杂,程序的可读性变得非常差,叫人没办法分清程序真的要表示的页面构架。
而新技术ASP.Net则通过Codebehind、用户控件与自概念控件等办法真的做到了代码的离别。这是一个了不起的进步,大伙可以在本文中看到离别代码后的ASP.Net程序的结构是多么的明确。
为了便于理解,这里设计的页面比较简单,页面分为三个主要的部分,头部包括一个AdRotator控件与一个Label控件;中部是一个登陆页面,包含两个TextBox控件、一个Label控件与一个Button控件;底部包括两个Label控件。
熟知ASP.Net的朋友,立刻就会意识到头部因为用了AdRotator控件,所以一定存在OnAdCreated事件以便在Label控件显示相应链接;而中部因为用Button控件做为提交按钮,所以一定有一个OnClick事件处置。
1 CodeBehind
第一大家就看看怎么用CodeBehind办法来达成代码与页面构架的离别,下面给出的源程序是主ASP.Net程序--Example1.aspx:
<% @ Page Src="csEventHandle.cs" Inherits="Aspcn" %>
例程中,大伙可以了解地看到程序中不包括任何C#、VB、Javascript来处置OnAdCreated与OnClick事件,但实行本程序,程序可以正常用。这便是用CodeBehinde的结果,事件处置已经被转移到其它程序中概念实行。请大伙注意本例中第一行的信息:
<% @ Page Src="csEventHandle.cs" Inherits="Aspcn" %>
一般在ASP.Net程序中,Page指令都在设定本程序应当用什么语言,而本例中没出现Language属性,而是出现了两个新的Page属性:Src与Inherits。Src属性设定事件处置真的的代码地方,Inherits属性则设定需要引入的类名。可以看到本例中概念事件处置的文件是EventHandle.cs,大家来看看它的具体内容: using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
public class Aspcn : Page
{
//声明Web Form中出现的控件
public Label lblAdText,lblUserName,lblPurview,lblMsgShow;
public TextBox tbUserName,tbPasswd;
public Button btnSubmit;
public AdRotator ad;
private string strConnString = "server=\Feidao;database=aspcn;Trusted_Connection=yes";
//处置Adrotator控件打造事件
public void AdCreated
{
lblAdText.Text = e.AlternateText;
}
public void Submit_Click
{
SqlConnection MyConn = new SqlConnection;
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;
SqlDataReader dr = MyComm.ExecuteReader;
if)
{
//登陆成功
lblMsgShow.Text = "登陆成功";
lblUserName.Text = dr["id"].ToString;
lblPurview.Text = dr["purview"].ToString;
}
else
{
//登陆不成功
lblMsgShow.Text = "登陆不成功";
}
dr.Close;
MyConn.Close;
}
}
进行事件处置是概念在一个类中的,因为需要与Web Forms有关联,所以此类还需要继承Page类。
剖析程序,大伙可以看到程序中对事件的处置操作是与普通的没有进行代码离别的程序是一样的,并没什么特别的地方。
用CodeBehind技术后,大伙需要多写一些代码,譬如声明控件等,或许大伙非常不喜欢多写如此的代码,但大伙也需要看到用了CodeBehind技术后,主程序的可读性大大增加了。在Example1.aspx中相信大伙非常快就能区别页面构架的每个部分,大伙想想这类构架假如在其它技术是不是能看得这样了解?
2 用户控件
CodeBehind技术真的达成了代码与构架的离别,比以前的技术前进了一大步,但它的缺点也是显而易见的,譬如主页面中部那个登陆区,假如内容丰富,HTML显示代码的依旧会占用非常大的地区,程序的可读性依旧会减少。
ASP.Net也提供知道决方法,这就是用户控件。
用户控件大家可以将它视为不需要编译的Server控件。即然是控件,那样就一定会遵从控件怎么使用。大家将Example1.aspx中的每一个Panel整体看成为一个控件,因此Example1.aspx的主体部分通过用用户控件便可以降低为只有三行:
<% @ Register TagPrefix="aspcn" TagName="Header" Src="UserControls/Header.ascx" %>
<% @ Register TagPrefix="aspcn" TagName="Logon" Src="UserControls/Logon.ascx" %>
<% @ Register TagPrefix="aspcn" TagName="Footer" Src="UserControls/Footer.ascx" %>
实行这个程序,其运行结果与用CodeBehind技术的结果是一样的,但目前的ASP.Net程序愈加容易区别页面构架了。
这三行代码,用了三个用户控件,这么少的代码大伙一眼就能了解的看到页面被分为三个部分。
要用用户控件就需要用Register指令,TagPrefix属性概念是的一个Namespace的名字,以保证它在这个页面的唯一性;TagName属性是在概念一个类的别名,因为用户控件实行时是被CLR编译成为类来实行的,所以就需要给本程序中每一个用户控件一个唯一的名字,以便于大伙区别;Src属性则是具体指出了用的用户控件的文件名。
用户控件的用法与普通Server控件一样:
namespace表示概念的命名空间,class则是相应的类名,具体的用法例子有:
下面是用户控件显示程序中所用的用户控件的具体内容:
Header.ascx
目前广告链接:
Logon.ascx
<% @ import Namespace="System.Data" %>
<% @ import Namespace="System.Data.SqlClient" %>
登陆窗口
用户名:
密码:
Footer.ascx
用户名:
权限:
每一个控件包括有自已的显示代码与相应的程序代码。
大家可以将一些常见的功能制作成为固定的用户控件,当需要时,大家就可直接拿来用,而无需用烦人的Crtl+C,Ctrl+V来"复制"、"粘贴"长长的一大堆代码。
用户控件不只做到了程序代码与页面构架的离别,而且还增加了代码重用性。
3 自概念控件
用户控件是很好的选择,但因为每一个用户控件都是一个ascx文件,当这类控件不少时,它们的用法就看上去比较零乱。此时大家便想能不能将一些比较一样的控件整理起来,在程序中仅需引用一次,便全部解决。这是个很好的想法,大家把这个想法说得愈加专业一些:"将多个类导入同一个命名空间"。呵呵,如何,这句话是否有点有耳熟?大伙快去查一查Server控件的概念,是否发现这句话是...
大家下面就要接触怎么样写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.Adverti百度竞价推广entFile = "AdBanners/ad.xml";
ad.BorderWidth = 0;
ad.AdCreated += new AdCreatedEventHandler;
this.Controls.Add;
this.Controls.Add);
//加入Label控件
lblAdText = new Label;
lblAdText.ForeColor = Color.Red;
this.Controls.Add;
}
private void OnAdCreated
{
this.lblAdText.Text = e.AlternateText;
}
}
//接着是Logon
public class Logon : Control,INamingContainer
{
private string strConnString = "server=\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);
//添加MsgShow Label控件
lblMsgShow = new Label;
lblMsgShow.ForeColor = Color.Red;
this.Controls.Add;
this.Controls.Add);
//添加UserName与Passwd TextBox控件
tbUserName = new TextBox;
this.Controls.Add;
this.Controls.Add);
tbPasswd = new TextBox;
tbPasswd.TextMode = TextBoxMode.Password;
this.Controls.Add;
this.Controls.Add);
//添加BtnSubmit Button控件
Button btnSubmit = new Button;
btnSubmit.Text = "登陆";
btnSubmit.Click += new EventHandler;
this.Controls.Add;
this.Controls.Add);
}
//显示完毕
private void Submit_Click
{
SqlConnection MyConn = new SqlConnection;
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;
SqlDataReader dr = MyComm.ExecuteReader;
if)
{
//登陆成功
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);
Label lblUserName = new Label;
lblUserName.ForeColor = Color.Red;
lblUserName.Font.Name = "Arial";
lblUserName.Text = this.UserName;
this.Controls.Add;
//this.Controls.Add);
this.Controls.Add);
Label lblPurview = new Label;
lblPurview.ForeColor = Color.Red;
lblPurview.Font.Name = "Arial";
lblPurview.Text = this.Purview;
this.Controls.Add;
}
}
}
上面和程序是将需要达成的功能,全部导入了自概念控件。程序中可以看到,在aspcn命名空间中包括三个类,这三个类正是构架三个主体部分。
要用自概念控件,还需要将原代码进行编译。
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 与As百度竞价推广bly。
当大家将程序编译好的aspcn.dll放入/bin目录后,这个自己撰写的Server控件便可以用了。
下面再来看看主体Web Form的程序内容:
<% @ Register TagPrefix="aspcn" Namespace="aspcn" As百度竞价推广bly="aspcn" %>
如何,相当简单明了吧。
引用大家自概念的控件,也相当简洁,仅需将Register指令的TagPrefix、Namespace、As百度竞价推广bly属性全部设定为aspcn。
至此,ASP.Net中三种代码与页面构架离别的办法已经介绍完毕。
三种办法各有优劣,本人比较倾向于用用户控件与CodeBinde技术结合用,由于他们均无需编译,相对来讲更容易用,假如你要保护你的代码,自概念控件则当然是你最好的选择。
期望本文对你的编程有所帮助。