Petshop4.0超级详细介绍(一)
今天辞职了,看了一下
petshop4.0,
通俗的把代码解释一下
,
希望能给初学者提供一些帮助,写的不好的地方还请大家理解!现在开始吧。
我们从启始页
Default.aspx
开始
,
微软的启始页当然是
Default.aspx
啦,该页面有一个用户控件
NavigationControl
先来说说它,从简单入手嘛
。
从它的
Page_Load事件开始:
protected
void Page_Load(object sender, EventArgs e)
{
GetControlStyle();//设置<td>的样式,在webconfig中已经配置了网站的全局样式App_Themes中有它的详细配置资料,在这里进行样式的选择
BindCategories();//这里对Repeater控件进行了绑定,请看BindCategories()方法;
//让它选择了连接会变颜色
string
categoryId = Request.QueryString["categoryId"];
if (!string.IsNullOrEmpty(categoryId))
SelectCategory(categoryId);
//对网站采用缓存处理,这里可以查看,说的很清楚
DependencyAccess -> TableDependency -> IPetShopCacheDependency
this.CachePolicy.Dependency = DependencyFacade.GetCategoryDependency();
}
private
void BindCategories() {
Category
category = new Category();//这里调用BLL(业务逻辑层),对产品的类别进行处理
repCategories.DataSource = category.GetCategories();
//这个方法返回一个
IList
<CategoryInfo>它的类型为CategoryInfo位于Model项目中该项目有点像与数据库中相对应的表用来放数据便于对数据处理, 使用Ilist将许多CategoryInfo实例放进去
repCategories.DataBind();
//这样Repeater控件的绑定就完成了
}
private
static readonly ICategory dal = PetShop.DALFactory.DataAccess.CreateCategory();
//数据抽象工厂不能继承此类
,相对应的方法,这样做可以实现动态创建类和调用类型的功能:
public
static PetShop.IDAL.ICategory CreateCategory() {
string className = path + ".Category";
return
(PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
//这里返回的是SQLServerDAL.Category它继承了
Icategory
接口因此要实现
GetCategories()与GetCategory()方法
}
//这里调用SQLServerDAL.Category.GetCategories()方法
public
IList<CategoryInfo> GetCategories() {
return dal.GetCategories();
}
//SQLServerDAL.Category.GetCategories()方法
public
IList<CategoryInfo> GetCategories() {
IList
<CategoryInfo> categories = new List<CategoryInfo>();
//使用using对
SqlDataReader
自动释放
using
(SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORIES, null)) {
while (rdr.Read()) {
CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
categories.Add(cat);
}
}
return categories;
}
昨天说到了Default.aspx页面今天来讲Products.aspx页面,该页面由有一个母版页和一个用户控件组成。
其中的用户控件中只包涵了一个
CustomList
自定义控件它继承至
DataList
并实现分页
:
public
event DataGridPageChangedEventHandler PageIndexChanged;
override
public object DataSource {
set {
try {
dataSource = (IList)value;
//非泛型列表的基接口,避免用户将没有继承Icollection的类型传递进来如int型之类的。
ItemCount = dataSource.Count; //获取dataSource中元素的数量
}
catch {
dataSource = null;
ItemCount = 0;
}
}
}
//重写BaseDataList.OnLoad()方法
override
protected void OnLoad(EventArgs e) {
if (Visible) {
string page = Context.Request[KEY_PAGE];
int index = (page != null) ? int.Parse(page) : 0;
SetPage(index); //初始化NewPageIndex属性
}
}
public
void SetPage(int index) {
OnPageIndexChanged(new DataGridPageChangedEventArgs(null, index));
}
//如果PageIndexChanged事件不为空则执行相对应的方法
virtual protected void OnPageIndexChanged(DataGridPageChangedEventArgs e) {
if (PageIndexChanged != null)
PageIndexChanged(this, e);
}
ProductsControl.ascx控件的Page_Load中
this
.CachePolicy.Dependency = DependencyFacade.GetProductDependency();////在我的前一篇文章中有介绍
现在来说说它的母版页MasterPage.master它的里面包涵了一个BreadCrumbControl用户控件用来实现产品的导航。其他的都是常用的web控件
接着与
Products.aspx
相关联的
Items.aspx
用来显示产品它主要由
ItemsControl.ascx
用户控件组成包含一个继承
Repeater
的自定义控件
CustomGrid
内部代码和
CustomList差不多。
<
tr
class="itemText">
<
td
colspan="2"><asp:HyperLink ID="lnkCart" runat="server" NavigateUrl='<%#string.Format("~/ShoppingCart.aspx?addItem={0}", Eval("Id")) %>'SkinID="lnkCart"></asp:HyperLink></td>
</tr>
<tr class="itemText">
<td colspan="2"><asp:HyperLink ID="lnkWishList" runat="server" NavigateUrl='<%# string.Format("~/WishList.aspx?addItem={0}", Eval("Id")) %>'SkinID="lnkWishlist"></asp:HyperLink></td>
</tr>
Petshop4.0超级详细介绍(三)
ShoppingCart.aspx中
Profile
提供的功能是针对用户的个性化服务。在
ASP.NET 1.x
版本时,我们可以利用
Session
、
Cookie
等方法来存储用户的状态信息。然而
Session
对象是具有生存期的,一旦生存期结束,该对象保留的值就会失效。
Cookie
将用户信息保存在客户端,它具有一定的安全隐患,一些重要的信息不能存储在
Cookie
中。一旦客户端禁止使用
Cookie
,则该功能就将失去应用的作用。
Profile
的出现解决了如上的烦恼,它可以将用户的个人化信息保存在指定的数据库中。
ASP.NET 2.0
的
Profile
功能默认支持
Access
数据库和
SQL Server
数据库,如果需要支持其他数据库,可以编写相关的
ProfileProvider
类。
Profile
对象是强类型的,我们可以为用户信息建立属性,以
PetShop 4.0
为例,它建立了
ShoppingCart
、
WishList
和
AccountInfo
属性。
<
properties
>
<
add
name
=
"ShoppingCart"type="PetShop.BLL.Cart"allowAnonymous="true"provider="ShoppingCartProvider"/>
<
add
name
=
"WishList"type="PetShop.BLL.Cart"allowAnonymous="true"provider="WishListProvider"/>
<
add
name
=
"AccountInfo"type="PetShop.Model.AddressInfo"allowAnonymous="false"provider="AccountInfoProvider"/>
</
properties
>
在我们为
web.config
配置文件中对
Profile
进行配置后,启动
Web
应用程序,
ASP.NET
会根据该配置文件中的相关配置创建一个
ProfileCommon
类的实例
(
单步调试可以看到创建
ProfileCommon
)
。该类继承自
System.Web.Profile.ProfileBase
类。然后调用从父类继承来的
GetPropertyValue
和
SetPropertyValue
方法,检索和设置配置文件的属性值。然后,
ASP.NET
将创建好的
ProfileCommon
实例设置为页面的
Profile
属性值。因而,我们可以通过智能感知获取
Profile
的
ShoppingCart
属性,同时也可以利用
ProfileCommon
继承自
ProfileBase
类的
Save()
方法,根据属性值更新
Profile
的数据源。
可选的 Boolean 属性。指定是否启用匿名标识。如果为 true,则使用 Cookie(或没有 Cookie 的值)来管理用户的匿名标识符。默认值为 false。
<
anonymousIdentification
enabled
=
"true"/>
在有些情况下,您的应用程序最初可能维护着匿名用户的个性化设置信息,但最后该用户登录到了您的应用程序中。在这种情况下,该用户的标识会从分配的匿名用户标识更改为身份验证进程提供的标识。
当用户登录(即不再是匿名用户)时,将引发 MigrateAnonymous 事件。如果有必要,可以对此事件进行处理,以便将信息从用户的匿名标识迁移到新的通过身份验证的标识。下面的代码示例演示用户通过身份验证时如何迁移信息。
void
Profile_MigrateAnonymous(Object sender, ProfileMigrateEventArgs e) {
ProfileCommon anonProfile = Profile.GetProfile(e.AnonymousID);
foreach
(CartItemInfo cartItem in anonProfile.ShoppingCart.CartItems)
Profile.ShoppingCart.Add(cartItem);
foreach (CartItemInfo cartItem in anonProfile.WishList.CartItems)
Profile.WishList.Add(cartItem);
// Clean up anonymous profile
ProfileManager.DeleteProfile(e.AnonymousID);
AnonymousIdentificationModule.ClearAnonymousIdentifier();
// Save profile
Profile.Save();
}
ASP.NET 使用此方法利用在 ASP.NET 应用程序配置文件 (Web.config) 中指定的属性值初始化 SqlProfileProvider
public
override void Initialize(string name, NameValueCollection config) {
if
(config == null)
throw new ArgumentNullException("config");
if(string.IsNullOrEmpty(config["description"])) {
config.Remove("description");
config.Add("description", "Pet Shop Custom Profile Provider");
}
if
(string.IsNullOrEmpty(name))
name = "PetShopProfileProvider";
if(config["applicationName"] != null&& !string.IsNullOrEmpty(config["applicationName"].Trim()))
applicationName = config["applicationName"];
base
.Initialize(name, config);
}