首页点击内容详细页时,跳转到了products.aspx这个页面,接下来就来分析一下这个页面了.
products.aspx页面代码很简单,只有几行
<%@ Page AutoEventWireup="true" Language="C#" MasterPageFile="~/MasterPage.master" Title="Products" Inherits="PetShop.Web.Products" CodeFile="~/Products.aspx.cs" %> <%@ Register Src="Controls/ProductsControl.ascx" TagName="ProductsControl" TagPrefix="PetShopControl" %> <asp:Content ID="cntPage" ContentPlaceHolderID="cphPage" runat="Server" EnableViewState="false"> <PetShopControl:ProductsControl ID="ProductsControl1" runat="server" /> </asp:Content>
由于NET2.0全面使用了母版页,所以基本的不必常改动的地方都放在这了。这也就简化了代码。而且开发的效率更高了。看了页面代码,加截了用户控件Controls/ProductsControl.ascx然后其他什么东西都没,那这样的话,直接分析这一用户控件的功能也就行了。打开ProductsControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductsControl.ascx.cs" Inherits="PetShop.Web.ProductsControl" EnableViewState="false" %> <%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %>
使用Register为注册用户控件这跟建立一个自定义用户控件又有点不同,因为少了个Scr,也就是用户控件的出处,使用了名称空间为PetShop.Web
<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>
使用了页面缓存技术,之前看了一篇分析说PetShop4使用了2种缓存机制,一种是应该程序缓存,一种是页输出缓存,OutputCache 设置了页级的缓存,时间为Duration为1000000秒,对page,categoryID控件建立缓存
先研究一下后台代码
protected void Page_Load(object sender, EventArgs e) { this.CachePolicy.Dependency = DependencyFacade.GetProductDependency(); }
cachedependency 2.0里的缓存机制 迟点再再学习一下缓存机制
还有一行是PageChanged()
/// <summary> /// Rebind control /// </summary> protected void PageChanged(object sender, DataGridPageChangedEventArgs e) { //reset index productsList.CurrentPageIndex = e.NewPageIndex; //get category id string categoryKey = Request.QueryString["categoryId"]; //bind data Product product = new Product(); productsList.DataSource = product.GetProductsByCategory(categoryKey); productsList.DataBind(); }
这一段从写法的结构上看像是在写切换页时数据的绑定.这里是实例化一个product然后再由他的GetProductsByCategory方法进行读取数据,追踪一下Product类看看
namespace PetShop.BLL { public class Product { private static readonly IProduct dal = PetShop.DALFactory.DataAccess.CreateProduct(); public IList<ProductInfo> GetProductsByCategory(string category) { if(string.IsNullOrEmpty(category)) return new List<ProductInfo>(); return dal.GetProductsByCategory(category); } public IList<ProductInfo> GetProductsBySearch(string text) { if (string.IsNullOrEmpty(text.Trim())) return new List<ProductInfo>(); string[] keywords = text.Split(); return dal.GetProductsBySearch(keywords); } public ProductInfo GetProduct(string productId) { if(string.IsNullOrEmpty(productId)) return new ProductInfo(); return dal.GetProduct(productId); } } }
来到了三层结果中的业务逻辑层了.再来研究一下这个类的作用
三个方法GetProductsByCategory(string category),根据类别返回一个IList<ProductInfo>的东西
用了IList<>,这个IList就是IndexedList,意思是说可以根据索引访问的列表。那个尖角括号是说,这里用了泛型
dal.GetProductsByCategory(category)这样就读到了数据?下一章再分析这个怎么来读取数据的。这里不讨论
第二个方法使用的是
GetProductsBySearch这个产品根据搜索关键字返回一下IList<>类型的方法
第三个是public ProductInfo GetProduct(string productId) 根据产品的ID返回一个ProductInfo这个是个实体类。
好了,不再深入解读。
返回来ProductsControl.ascx 要不越读越离得远了,按照三层的思想慢慢再看。
productsList.DataSource = product.GetProductsByCategory(categoryKey); productsList.DataBind();
productsList的数据源来自己实例化的product所读取categoryKey这个分类所在的全部数据,页DataSource绑定是的一个IList<>类型。怎么productsList.DataSource可以绑定这种类型吗?等一下再分析。
然后进行绑定。这样产品的页面就可以显示了。
但看回HTML的页面里,有些和其他地方不同的东西
<PetShopControl:CustomList ID="productsList" runat="server" EmptyText="No products found." OnPageIndexChanged="PageChanged" PageSize="4" RepeatColumns="2" CellPadding="16" CellSpacing="0" Width="500px"> <ItemTemplate> <table cellpadding="0" cellspacing="0"> <tr> <td valign="top" width="91"><a href='Items.aspx?productId=<%# Eval("Id") %>&categoryId=<%# Eval("categoryId") %>'><img id="imgProduct" alt='<%# Eval("Name") %>' src='<%# Eval("Image") %>' style="border-width: 0px;" runat="server" /></a></td> <td width="26"> </td> <td valign="top" width="120"><a href='Items.aspx?productId=<%# Eval("Id") %>&categoryId=<%# Eval("categoryId") %>'><div class="productName"><%# Eval("Name") %></div></a><div class="productDescription"><%# Eval("Description") %></div></td> </tr> </table> </ItemTemplate> <ItemStyle HorizontalAlign="Left" VerticalAlign="Top" /> </PetShopControl:CustomList>
PetShopControl:CustomList 这个是什么东西,像是自定义的控件,CustomList是个自己写的东西,并不是控件里自带的。
存在于app_code目录,文件名:CustomList.cs
public class CustomList : DataList { //Static constants protected const string HTML1 = "<table cellpadding=0 cellspacing=0><tr><td colspan=2>"; protected const string HTML2 = "</td></tr><tr><td class=paging align=left>"; protected const string HTML3 = "</td><td align=right class=paging>"; ....
原来是继承了DataList对象,这样,CustomList就有了DataList的功能了。
override public object DataSource { set { //This try catch block is to avoid issues with the VS.NET designer //The designer will try and bind a datasource which does not derive from ILIST try { dataSource = (IList)value; ItemCount = dataSource.Count; } catch { dataSource = null; ItemCount = 0; } } }
这里重写了DataSource,数据源的绑定是一个IList类型以及读取数据后的显示问题。这样Products.aspx这页面也就差不多分析完了
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/clongge/archive/2008/08/06/2775387.aspx