技术开发 频道

ASP.NET2.0:AdventureWorks贸易系统分析


上一篇:系统简介

【IT168专稿】


   本文将关注ASP.NET Web站点的实现。使用Visual Studio 2005可创建新的Web站点。当Web站点创建后,可添加指向业务逻辑组件AdventureWorksTraderBiz的引用。注意,与EntLib配置相关的所有配置设置都存储在Web.config文件中。本文的内容与业务过程密切相关,主要包括产品类别显示过程、产品子类别显示过程、产品显示过程所涉及的Web站点。在开始讲解这些过程之前,首先说明用于整个Web站点的母版页。

1. 母版页


    专业的Web站点中所有页面应该具有标准化的外观。例如,常用的布局之一是在页面左边布置有导航菜单,版权信息在底部,内容在中间。如果在每个Web页面中复制通用的逻辑和外观来维护统一性是很困难的。在ASP.NET 2.0中,使用母版页来实现这个工作就很简单了。开发人员只需要在母版页中编写一次通用的内容即可。母版页可作为一个或者多个Web页面的模板。每个ASPX Web页面仅需要定义自身的唯一内容,接着内容将插入母版页布局中的特定区域。
示例1显示了名为Common.master的母版页代码,该母版页将用于AdventureWorks贸易站点。
示例1:实现外观一致的母版页
<%@ Master Language="C#" %> 
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Master Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Table ID="tblTop" BackColor="Gainsboro" runat="server"
Width="100%" Height="108px" ForeColor="DarkCyan">
<asp:TableRow runat="server" HorizontalAlign="Center">
<asp:TableCell runat="server" ColumnSpan="2">
<asp:Label ID="Label1" runat="server" ForeColor="Black"
Font-Size="Medium">AdventureWorks Trader System
</asp:Label>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:Table ID="Table6" runat="Server" Width="954px">
<asp:TableRow runat="server">
<asp:TableCell runat="server">
<asp:Table ID="Table1" BackColor="Gainsboro" runat="server"
Width="100%" ForeColor="DarkCyan" Height="290px">
<asp:TableRow ID="TableRow1" runat="server"
HorizontalAlign="Center">
<asp:TableCell ID="TableCell1" runat="server">
<asp:HyperLink runat="server" Text="Product Categories"
NavigateUrl="~/ProductCategoryDisplay.aspx">
</asp:HyperLink>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="TableRow3" runat="server"
HorizontalAlign="Center">
<asp:TableCell ID="TableCell3" runat="server">
<asp:HyperLink ID="HyperLink1" runat="server" Text="Product
Sub Categories" NavigateUrl="~/ProductSubcategoryDisplay.aspx" />
</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="TableRow4" runat="server" HorizontalAlign="Center">
<asp:TableCell ID="TableCell4" runat="server">
<asp:HyperLink ID="HyperLink2" runat="server" Text="Products" NavigateUrl="~/ProductDisplay.aspx" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:TableCell>
<asp:TableCell runat="server">
<asp:Table ID="Table2" BackColor="Gainsboro" runat="server" Width="100%" ForeColor="DarkCyan"
Height="290px">
<asp:TableRow ID="TableRow2" runat="server">
<asp:TableCell BackColor="#FFFFE1" ID="TableCell2" runat="server">
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>
   母版页封装了Web站点所有页面的页头和左边导航信息。既然读者已经了解了母版页,下面讲解提供核心功能的内容页。首先,讨论产品类别显示过程。
2. 产品类别显示过程


    在产品类别显示过程中,用户可浏览AdventureWorks数据库中的类别列表。另外,用户还可以浏览属于一个产品类别的产品子类别。通过单击产品类别名称,用户能够访问产品子类别。实例2列举了页面的实现代码。

    示例2:实现继承自母版页的产品类别显示页面
<%@ Page Language="C#" MasterPageFile="~/Common.master" Title="Product Categories Display" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:ObjectDataSource ID="categorySource" EnableCaching="true"
SqlCacheDependency="CommandNotification" CacheDuration="Infinite"
TypeName="AdventureWorksTraderBiz.ProductCategoryBiz"
SelectMethod="GetProductCategories" runat="server">
</asp:ObjectDataSource>
<asp:Label runat="server" ID="lblHeading" Font-Size="Medium"
Font-Underline="False" ForeColor="#0000C0">
Click on the Category to go to the SubCategories
</asp:Label><br />
<br />
<asp:GridView HeaderStyle-HorizontalAlign="Center"
HeaderStyle-Font-Bold="True" HeaderStyle-BackColor="blue"
HeaderStyle-ForeColor="White" AutoGenerateColumns="False"
ID="gridCategories" runat="server" DataSourceID="categorySource">
<Columns>
<asp:BoundField ReadOnly="True" HeaderText="CategoryID"
DataField="ProductCategoryID" />
<asp:HyperLinkField HeaderText="Name" DataTextField="Name"
DataNavigateUrlFields="ProductCategoryID"
DataNavigateUrlFormatString="ProductSubcategoryDisplay.aspx? ProductCategoryID={0}" />
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Row Guid" DataField="Rowguid" />
<asp:BoundField HeaderText="Modified Date" HtmlEncode="false" DataFormatString="{0:MM/dd/yyyy}"
DataField="ModifiedDate" />
</Columns>
</asp:GridView>
</asp:Content>
    示例2首先声明了名为categorySource的ObjectDataSource控件。在查看代码之前,需要理解ObjectDataSource控件的两个重要属性。TypeName属性用于设置该控件绑定到的类名称。SelectMethod属性用于设置类调用的方法名称。使用这些属性能够设置类名称以及绑定到ObjectDataSource控件的类方法。对于categorySource控件而言,这些属性分别设置为“AdventureWorksTraderBiz.ProductCategoryBiz”和“GetProductCategories”。下一步,将categorySource控件的数据绑定到名为gridCategories的GridView控件,方法是将GridView的DataSourceID属性值设置为categorySource。

    注意,ObjectDataSource控件还通过设置缓存属性,例如EnableCaching,CachDuration和SqlCacheDependency来实现缓存功能。将SqlCacheDependency属性设置为CommandNotification,指示ASP.NET应该为ObjectDataSource控件创建基于通知的依赖。

    另外,为了使用基于通知的依赖,需要在首次执行SQL查询之前,在应用程序中调用System.Data.SqlClient.SqlDependency.Start()方法。该方法可置于Global.asax文件的Application_Start()事件中。

     SQL Server 2005的缓存依赖在接收更改通知的类型方面更具有灵活性。SQL Server 2005监视特定SQL命令结果集导致的修改。如果数据库中命令的结果集导致了变化,那么依赖功能会使缓存项无效。SQL Server 2005提供了行级别的通知。


3. 产品子类别显示过程


    产品子类别页面允许向用户显示所有产品子类别的列表,然后通过所有产品列表中包括的各个子类别进行导航。示例3说明了产品子类别页面的实现。

   示例3:产品子类别显示页面
<%@ Page Language="C#" MasterPageFile="~/Common.master" Title="Product Sub Category Display" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:ObjectDataSource ID="subCategorySource"
TypeName="AdventureWorksTraderBiz.ProductSubcategoryBiz"
SelectMethod="GetProductSubCategories" runat="server">
<SelectParameters>
<asp:QueryStringParameter QueryStringField="ProductCategoryID"
Direction="Input" Name="productCategoryID" DefaultValue="1"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:Label runat="server" ID="lblHeading" Font-Size="Medium"
Font-Underline="False" ForeColor="#0000C0">
Click on the SubCategory to go to the Products
</asp:Label><br />
<br />
<asp:GridView HeaderStyle-HorizontalAlign="Center"
HeaderStyle-Font-Bold="True" HeaderStyle-BackColor="blue"
HeaderStyle-ForeColor="White" AutoGenerateColumns="False"
ID="gridSubCategories" runat="server" DataSourceID="subCategorySource">
<Columns>
<asp:BoundField ReadOnly="True" HeaderText="SubcategoryID"
DataField="ProductSubcategoryID" />
<asp:BoundField HeaderText="CategoryID" DataField="ProductCategoryID" />
<asp:HyperLinkField HeaderText="Name" DataTextField="Name"
DataNavigateUrlFields="ProductSubcategoryID"
DataNavigateUrlFormatString='"ProductDisplay.aspx?' ProductSubcategoryID="{0}" />
<asp:BoundField HeaderText='"Row' Guid" DataField="Rowguid" />
<asp:BoundField HeaderText='"Modified' Date" HtmlEncode="false" DataFormatString="{0:MM/dd/yyyy}" DataField="ModifiedDate" />
</Columns>
</asp:GridView>
</asp:Content>
    示例3包括名为subCategorySource的ObjectDataSource控件,该控件绑定了ProductSubcategoryBiz类的GetProductSubCategories()方法。正如前文讲解的那样,GetProductSubCategories()方法可接受产品类别ID为参数,同时返回属于该产品类别的所有子类别信息。为了调用这个方法,subCategorySource控件应该将产品类别ID(由产品类别显示页面返回)传递给该方法。在这种情况下,使用QueryStringParameter集合获取产品类别ID。为此,将QueryStringParameter模板的QueryStringField设置为查询字符串字段名称,同时将Name属性设置为GetProductSubcategories()方法参数的名称。这样在前面页面选中的产品类别ID则用于SQL查询的参数。开发人员还可以使用DefaultValue属性设置产品类别ID默认值为1。当首次请求页面时,将使用默认值。

4. 产品显示过程


   示例4列举列举了产品页的实现代码。
   示例4:实现产品显示页面
<%@ Page Language="C#" MasterPageFile="~/Common.master" Title="Products Display" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="Server">
<asp:ObjectDataSource ID="productSource" runat="server"
TypeName="AdventureWorksTraderBiz.ProductBiz"
SelectMethod="GetProducts">
<SelectParameters>
<asp:QueryStringParameter QueryStringField="ProductSubcategoryID"
Direction="Input" Name="productSubcategoryID" DefaultValue="1"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:Label runat="server" ID="lblHeading" Font-Size="Medium"
Font-Underline="False"
ForeColor="#0000C0">
List of Products
</asp:Label><br />
<br />
<asp:GridView HeaderStyle-HorizontalAlign="Center"
HeaderStyle-Font-Bold="True" HeaderStyle-BackColor="blue"
HeaderStyle-ForeColor="White" AutoGenerateColumns="False"
ID="gridProducts" runat="server"
DataSourceID="productSource">
<Columns>
<asp:BoundField ReadOnly="True" HeaderText="ProductID"
DataField="ProductID" />
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Product Number" DataField="ProductNumber" />
<asp:BoundField HeaderText="Color" DataField="Color" />
<asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
<asp:BoundField HeaderText="Modified Date" HtmlEncode="false" DataFormatString="{0:MM/dd/yyyy}"
DataField="ModifiedDate" />
</Columns>
</asp:GridView>
</asp:Content>
    示例4中所示的代码与示例3非常类似,除了本页面中的ObjectDataSource控件调用了不同的方法来获取所有产品。

小结

    在这个实例中,读者已经学习了各种很好的用于创建高效ASP.NET 2.0 Web站点的实践技巧,包括使用EntLib应用程序块,以及ASP.NET和SQL Server 2005的新功能。该实例所讨论的应用程序说明了将应用程序块集成到真实ASP.NET站点的方法,同时还讲解了泛型集合的使用方法。此外,本实例还讨论了ObjectDataSource控件如何支持分层应用程序设计,从而允许开发人员直接将对象方法的输出绑定到ASP.NET页面中的控件。希望读者在自己的项目中能够因地制宜的应用这些技术特性。
0
相关文章