ASP.NET重用代码技术 - 代码绑定技术
(苏红超 编译)
导读
代码绑定是ASP.NET提供的一个重要的新技术。本文将会为您展示如何利用代码绑定技术来实现Web页面表示层和商业逻辑代码的分离,并建议您使用代码绑定技术实现代码的可重用。在接下来的另外一篇文章当中,我们会给出另外的一种实现代码可重用的实现技术。
ASP.NET中的代码绑定技术
当你在建立自己的ASP.NET应用程序的时候使用代码绑定技术带来的一个主要的优点是:它可以让你很容易的将可见层(那些HTML代码和服务器端控件)同你的表现代码(这些代码有可能是VB,C#或者其他的任何.NET支持的语言)自由的分离开来。当你有一个多人的开发小组开发同一个项目的时候,这个优势就更加明显。某个人可能负责web页面的设计和编写,而另外的一个人可能是负责页面相关的具体程序的开发。因而通过将各自的工作范围分割的做法,可以轻松的实现双方不会在无意之间破坏对方的工作成果。当然,要做到页面能够正常的运行,各自之间的良好沟通也是必不可少的。
当我们使用代码绑定技术的时候,可视层的代码是存在于后缀为ASPX的文件当中。这是一个新的.NET扩展名,用来描述一个ASP文件。在以前的ASP中很难做到一个页面当中没有任何脚本程序只有HTML代码(当然如果你毫无意义这样作也是可以的)。然而现在代码绑定技术允许ASPX文件仅仅包含HTML代码和服务器端控件,并且允许开发者完全的使用面向对象方式来实现一个解决方案。通过一个分开的代码文件中访问这个ASPX文件的这样一种机制可以实现上面的设想。这些文件在浏览器第一次发出请求的时候被编译成单独的二进制文件,如下图所示:
代码绑定文件是一个独立的文件,可以使用任何.NET支持的语言编写。比如,使用Visual Basic .NET来编写这些文件,它的扩展名将会是“vb”。这个代码绑定的代码包含了所有的和表示层相关的事件、功能函数、方法等等。每一个ASPX文件只能通过一个代码绑定文件实现。
当然,通过一定的工作,代码绑定技术可以用在多种需要可重用代码的环境当中。每一个ASPX文件有他们自己的代码绑定文件,并且多个功能类似的ASPX文件可以共享一个公共的代码绑定文件。本文会展示如何实现你的ASPX文件的最基本代码绑定技术,并且会详细讨论代码绑定技术如何被应用于代码可重用方面。以后的文章当中,我们会陆续介绍.NET架构提供的其他也可以容易实现代码重用的技术,比如用户控件,编译的集合等等。 让我们来大致看一下一个例子,来看看如何实现代码绑定技术。为了简单起见,我们的例子会以一个简单的搜索页面作为开始。当我们一步步通过代码绑定技术建立我们的搜索页面之后,我们就会能够看到代码绑定技术是如何实现一个代码重用的ASPX文件。为了使得ASP.NET程序正常运行,你必须安装.NET架构Beta1。如果要使得本文提出的程序正常运行,您必须安装SQL Server2000。
一步步实现代码绑定技术
首先,我们需要建立一个.ASPX文件。在这个ASPX文件当中,我们需要使用@page指令来说明我们正在使用一个代码绑定的文件。为了做到这一点,我们需要设置两个属性:src以及inherits。Src属性指定了包含实际代码的文件,如果没有这个属性,则在属性inherits中指定的类会从编译时候传递的参数中寻找。Inherits属性指定在源文件中存在的类。这个类需要从Page类中派生。我们的具体例子如下:
<%@ Page Language="vb" AutoEventWireup="false" src="Search.VB" Inherits="Search"%>
接下来,我们需要添加适当的控件来建立我们的用户界面。既然我们的例子页面是一个简单的搜索页面,我们只需要加入很少的一部分控件就可以了。除了一些标签标记,我们需要增加一个搜索的文本框,一个提交搜索的按钮,以及一个DataGrid控件来显示数据库中的内容。下面是代码:
<%@ Page Language="vb" src="search.vb" inherits="Search" %>
<html>
<head>
<meta content="Microsoft Visual Studio.NET 7.0">
<meta content="Visual Basic 7.0">
</head>
<body>
<form method="post" runat="server">
<p>
<asp:Label id=lblTitle runat="server" Font-Names="Arial"
Font-Bold="True">Worldwide Books Search</asp:Label>
</p>
<p>
<asp:Label id=lblCriteria runat="server" Font-Names="Arial"
Font-Italic="True">Search Criteria</asp:Label><br>
<asp:TextBox id=txtSearch runat="server"></asp:TextBox>
</p>
<p>
<asp:Button id=cmdSearch runat="server" Text="Search"></asp:Button>
</p>
<p>
<asp:DataGrid id=grdBooks runat="server" Font-Names="Arial"
ForeColor="Black" Font-Size="Smaller">
<property>
<asp:TableItemStyle HorizontalAlign="Left" VerticalAlign="Top"
BackColor="Salmon">
</asp:TableItemStyle>
</property>
<property>
<asp:TableItemStyle ForeColor="White" BackColor="Silver">
</asp:TableItemStyle>
</property>
<property>
<asp:TableItemStyle HorizontalAlign="Left" VerticalAlign="Top" BackColor="White">
</asp:TableItemStyle>
</property>
<property>
<asp:TableItemStyle Font-Bold="True" ForeColor="White"
BackColor="Navy">
</asp:TableItemStyle>
</property>
</asp:DataGrid>
</p>
</form>
</body>
</html>
下面是运行后的界面:
下面,我们需要建立我们的代码绑定页面。(如果我们使用Visual Studio.NET Beta1来构建我们的ASPX文件的话,那么系统会在ASPX生成的同时,自动的产生相关的代码绑定文件)。在这篇文章,我们的例子使用的VB语言,当然其他任何被支持的语言(比如:C#,C++)也能被使用。为了使得代码绑定页面正常工作,一些项目需要在源文件当中包含进来。如下:
一些相关的集合名称控件需要引用
ASPX文件所要继承的公共类需要存在,并且这个类需要继承System.Web.UI.Page
控制变量的声明
对于我们的例子,我们需要引用System.Web.UI.WebControls这个名称空间来存取Web控件的类。为了操作数据库中的资料,我们需要引用System.Data和System.Data.SQL这两个名称空间。引用System.Collections名称空间允许我们使用哈希表来捕获应用程序的相关设定。通过Microsoft.VisualBasic这个名称空间,我们可以使用一些VB的函数库。
接下来,我们需要建立一个公共的类使得我们的ASPX文件可以继承它。类的名称应当和我们的ASPX文件中指令@page的属性inherints指定的名称相同。这个类应当继承System.Web.UI.Page。通过继承上面的类,我们建立的类就可以存取ASPX页面了。
最后,我们需要声明我们在程序中用到的控件,尤其是我们的按钮控件,这样我们就可以捕获到按钮的click事件了。为了能做到这点,我们需要在类中建立这些用来表现我们的按钮和文本框的变量。这些变量需要使用WithEvents关键字来建立,如下所示:
Protected WithEvents cmdSearch As System.Web.UI.WebControls.Button
Protected WithEvents txtSearch As System.Web.UI.WebControls.TextBox
这样,我们的代码绑定页面看起来如下:
Option Strict Off
Imports System.Data
Imports System.Data.SQL
Imports System.Web.UI.WebControls
Imports System.Collections
Imports Microsoft.VisualBasic
Public Class Search
Inherits System.Web.UI.Page
Protected WithEvents cmdSearch As System.Web.UI.WebControls.Button
Protected WithEvents txtSearch As System.Web.UI.WebControls.TextBox
Protected Sub Search_Load(ByVal Sender As System.Object, ByVal e As System.EventArgs)
If Not IsPostback Then ' Evals true first time browser hits the page
End If
End Sub
End Class
应当注意到的是,如果我们是使用Visual Studio.NET Beta1来工作的,它会自动的帮助我们生成大部分的代码。
这样就基本完全的实现了一个使用了代码绑定技术的页面的编写。对于我们的例子来说,很显然我们需要加入实际的代码来真正实现搜索和结果的显示。所以,我们要建立一个公共的子过程,在搜索按钮被按下的时候会调用这个公共的子过程。在我们的例子当中,相应的代码大致如下:
Public Sub cmdSearch_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmdSearch.Click
关键字Handles表示当cmdSearch按钮的click事件被触发的时候会执行我们的这个公共子程序。(另外需要做的一件事情是,需要在page_load事件中监测Page.IsPostBack的值是否是true,在监测Page.ISPostBack属性的时候,我们也同时进行真正的搜索工作)。接下来的代码就只是简单的按照输入的条件在数据库pubs中搜索,并且返回搜索结果给DataGrid控件。
可重用表现怎样?
上面我们做的工作的成果就是将我们的用户界面从程序代码中分离了出来。但是这对可重用起到了什么激励作用呢?代码绑定技术对于组织程序代码来讲是一项卓越的技术,但是它或许仅仅对那些在某些环境下的代码重用有帮助作用,主要是这个技术非常适合于在需要建立两个为了相同或相似目的页面的时候使用,这时候起到了很好的代码重用的作用。比如,假设你需要为两种不同类型的用户建立两个登陆页面,并且两个页面在外观界面上面有很大不同(但是实际上的起到的作用是非常类似的)。这样建立两个ASPX文件,他们共用一个相同的代码绑定文件是非常明智的做法。另外的一个例子则看起来有些极端化—那就是或许你的应用程序当中有一些页面同时需要德文和英文两个版本!
对于我们的例子,我们接下来要建立一个看起来比较吸引人的页面,因为使用了不少的图片;如果要看到最佳的效果,需要浏览器采用800 X600的分辨率。而我们最初的原始页面则可以用到在一个Pocket PC上面的浏览器观看(在Pocket PC上面屏幕大小是非常宝贵的,而不建议采用过多毫无意义的图片)。这样,我们只需要建立一个另一个简单的ASPX文件,在这个ASPX文件的@page指令当中引用相同的源文件(src属性)以及类(inherits属性)。这个比较美观的页面界面如下:
当你提交一个搜索请求的时候,无论是我们的第一个原始页面还是现在的这个比较美观的页面,都会通过search.vb这个文件来执行搜索动作。返回结果的页面因为各自的样式设置不同会稍稍有所差别,但是实际上他们使用的都是同一段代码而得到的需要的数据。
我们的第一个简单的页面搜索之后的界面如下:
相同的,界面比较美观的页面返回的搜索结果界面如下:
局限性
使用代码绑定技术实现的代码重用有没有一些局限性呢?不幸的是,答案是肯定的,这个技术有一些主要的局限性。其中一个较大的局限性就是一个ASPX文件仅仅能够继承一个类。这就意味着开发者将不得不为每一个ASPX页面开发一个针对它的代码绑定页面,除非是遇到了上面的我们曾经描述过的相似情节才可以多个ASPX文件共享一个公用的代码绑定页面。
另外的一个代码重用的限制是:如果那些ASPX页面差别很大,你会在重利用代码绑定页面的时候有一些麻烦。记住,在代码绑定类方面,在ASPX页面上的那些控件是使用WithEvents关键字来声明的。如果一个控件在其中的某一个ASPX页面上面,而另外的一个ASPX页面没有这个控件,你就不能使用控件声明的方式,而要使用Page.FindControls方法来的到这个控件的一个引用,当然前提是如果在某个页面上存在这个控件的话(如果不存在,会返回”nothind”)。通过这个方法,我们可以调用控件的属性、方法,但是不能捕获到控件的事件。因此,如果控件不同时存在于页面上的话,我们就不能使用event handling。如果我们想要能够捕获控件的事件,我们需要使用另外的一种代码重用技术—用户控件技术,这是另外的一篇文章探讨的内容了。
总结
在这篇文章当中,我们探讨了使用代码绑定技术的基本概念,同时也给出了一个实际的例子,就是两个不同的ASPX文件共享一个通用的代码绑定类。我们也探讨了使用代码绑定技术实现代码重用的优点和局限性