资源预览内容
第1页 / 共79页
第2页 / 共79页
第3页 / 共79页
第4页 / 共79页
第5页 / 共79页
第6页 / 共79页
第7页 / 共79页
第8页 / 共79页
第9页 / 共79页
第10页 / 共79页
亲,该文档总共79页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第五章 学习情境:使用ASP.NET状态管理实现购物车,第五章 学习情境:使用ASP.NET状态管理实现购物车,5.1 学习情境引入 5.2 基础知识:ASP.NET的状态管理 5.3 基本知识2:跨页面数据传递 5.4 决策与计划 5.5 实施 5.6 检查与评价 5.7 训练,5.1 学习情境引入,5.1.1 网上书店的购物车功能需求和主要问题 5.1.2 网上书店购物车功能展示 5.1.3 网上书店购物车技术分解,5.1.1网上书店的购物车功能需求和主要问题,1功能需求 网上书店需要购物车功能,先购书,然后下订单,由于下订单需要数据库操作,本章只介绍购书部分,图 51 会员购书行为的详细描述,会员的购书行为如图 51,结合前面网上书店系统的展示,购书过程描述为: 会员在主页搜索到了某些图书; 通过主页书名超链接到该图书的详细信息页面,填入购买数量,将其加入购物车; 在购物车页面中浏览刚才的购物车数据(也可以删除购物车数据)。,5.1.1网上书店的购物车功能需求和主要问题,主要问题 (1)问题描述 记录多次购书数据:每个用户可以连续重复上述的购书过程,以购买不同的图书,而在个人购物车中,可以看到每次购买得到的图书数据。也就是图书详细信息页面能够记录每次的购书数据。 记录多用户购书数据:一个网站可能多个用户同时访问,每个用户都将在个人购物车中看到自己的购物数据。也就是图书详细信息页面在记录购书数据时能够区分用户。 跨页传递购书数据:购物车页面能够获得图书详细信息页面的购物数据,用来浏览和管理。即可以在两个页面请求之间记住购物车信息。 问题分析 以我们桌面程序设计的经验来看,这根本不应成为问题,只需要加一些变量,每次用户单击时记录一些值就可以实现。但在网站程序中却成为了问题,因为HTTP协议是没有“记忆”的,它本身不会记住是哪个用户曾经访问过哪个网页,对于“无记忆”的HTTP协议而言,某个用户第一次访问页面BookDetails.aspx和第二次访问页面BookDetails.aspx之间没有什么联系,它不知道这是两次不同的购书。同样,也不知道是否不同的用户来访问。让我们看例 51。,5.1.1网上书店的购物车功能需求和主要问题,例 51 设置页面字段变量,无法实现计数的反面例子。在一个新的Web窗体页中,添加一个Button,修改其Text为“提交”,并编写如下的后台代码:,); public partial class _Default : System.Web.UI.Page int requestTimes = 0; protected void Page_Load(object sender, EventArgs e) requestTimes = requestTimes + 1; Response.Write(requestTimes ,在浏览器中查看本页面,多次点击“提交”按钮,查看网页显示的数值。 结果与分析:由于HTTP协议没有“记忆”,默认情况下,ASP.NET 每次收到请求都会重新实例化对应的页面类,造成requestTimes变量的值每次都初始化为0,因此该页面总是显示1。 为什么ASP.NET要每次都重新实例化对应的页面类?这是因为我们设计的是动态网页,可能有许多用户同时访问我们的网站,即使单个用户也可能多次和网页交互,这些用户即使都访问页面BookDetails.aspx,也可能看到不同的页面BookDetails.aspx:比如用户甲在浏览图书1的详细信息,用户乙则在浏览图书2的详细信息等等。所以不能事先实例化好页面BookDetails类,等待用户来请求,那会导致给他们响应有同样数据的页面实例。而只能是收到一个请求,就根据用户请求实例化所请求的页面,如果不加处理,每次请求所得的页面实例成员都是初始状态,字段变量值总是初始值。 看来,要避免这种“狗熊掰棒子”的结果,必须让HTTP协议变得有“记忆”。要让HTTP协议变得有“记忆”,实际上是一个保持状态的问题,也就是服务器在收到请求时,要能够得到上次请求的状态(包括网页的数据和客户端的标识等)。ASP.NET中有丰富的状态保持方法,适用于各种场合。保持了状态,就可以解决前面提到的问题了。,5.1.2网上书店购物车功能展示,从教材网站下载BookStoreWebSite源码,在本机调试运行。从首页以“test”用户名登录,单击某书名链接,则会打开图书详细信息页面,如图 51所示,输入购买数量,单击“购买”按钮。重复此过程若干次,以建立多条购书数据。单击页面上部“购物车”链接查看购物车,如图 52。 重新打开一个IE程序窗口(不能是选项卡),以另一个用户名“ee”登录,按照前述过程,购买不同的若干图书。再查看其购物车,如图 53,比较两图可知,“ee”用户、“test”用户能够分别保存每次的购物数据。,5.1.3网上书店购物车技术分解,1技术分解 开发实现购物车的技术方案并不唯一,但总是要既保持购物车数据状态,并进行跨页传递,所以,ASP.NET中有以下两部分相关技术: (1).ASP.NET的状态管理 ASP.NET采用多种技术来保持页面级别的状态,以及其他级别的状态,使得动态网站的开发变得简单而灵活,这是ASP.NET的核心技术。 对于程序员,使用ASP.NET提供的状态,是很容易的,但要灵活运用它们,就需要了解aspx页面的生命周期,熟悉了页面生命周期后,ASP.NET网站开发中的许多问题就可以迎刃而解,这也是我们把状态管理作为ASP.NET的核心技术的理由之一。,图 52 图书详细信息页面,图 53 “test”用户的购物车,图 54 “ee”用户的购物车,(2).ASP.NET跨页面数据传递技术 在页面之间传递数据的技术也很多,有的完全是传统的HTTP协议所支持的,有的只在ASP.NET的支持下才能使用,这也是与页面生命周期有关的常用技术。 2.学习安排 学习ASP.NET状态管理、跨页数据传递的相关知识后,实现购物车功能,并进行检查和评价,是本章的主要内容。 页面生命周期知识部分,理解起来有一定的难度,对初学者列为选学内容。但要成为一个熟练的ASP.NET开发者,页面生命周期是必须掌握的内容,建议初学者在实施中遇到问题后,反复查阅此部分内容,以将其逐步掌握。,5.2 基本知识1:ASP.NET的状态管理,5.2.1 视图状态 5.2.2 应用程序状态 5.2.3 会话状态 5.2.4 Cookie状态(选学) 5.2.5 自测 5.2.6 演练,5.2.1 视图状态,视图状态(ViewState),是使HTTP协议变得“有记忆”的关键技术,深入了解了视图状态,就能理解ASP.NET基于事件编程的许多重要工作原理。 在每次请求发生(包括原始请求)后,视图状态数据由ASP.NET在服务器端生成,默认情况下,存放在页面中的“_VIEWSTATE”隐藏域中,该隐藏域数据和页面的其他数据一起,随HTTP响应数据发送给客户端浏览器,隐藏域数据对用户不可见,也就不会因用户的正常操作而改变,当用户再次请求本网页时,随HTTP请求的Post数据一起,再发回服务器端,由ASP.NET处理。 视图状态的这个处理过程,是由ASP.NET自动完成的。默认情况下,所保存的数据也是自动筛选的,这些数据涉及Web窗体内几乎所有服务器控件,HTML控件不被保存。 除了自动筛选的视图状态数据,ASP.NET也提供给程序员将自定义数据(ViewState变量)保存在视图状态中的功能。 视图状态只能在本网页与服务器的往返中保持,而不能在不同网页之间传递,这是和其它状态所不同的地方。 关于视图状态,要学会ViewState变量使用的基本技能,要在理解视图状态和页面生命周期事件的关系的基础上,掌握何时可以禁用自动的视图状态。,1. 视图状态隐藏域,隐藏域并不是ASP.NET的新技术,而属于传统的HTML技术,是客户端页面代码中的一个标记,浏览器并不将其呈现给用户,所以称为隐藏域。 ASP.NET中用于存放视图状态数据的隐藏域是自动生成、经过编码的HTML标记,程序员和用户都不参与该区域的数据读写,在网页回发时,隐藏域数据随着HTTP请求发回服务器,由ASP.NET处理。例 52展示了视图状态隐藏域,例 53展示了视图状态隐藏域数据随着HTTP请求回发的情况。 ASP.NET还提供了HiddenField服务器控件,也会生成客户端隐藏域标记,程序员可以用HiddenField控件保存自定义信息,在网页回发时,程序员还可以通过读取该控件的值,从而取得HTTP协议的“记忆”。例 54利用HiddenField控件“记忆”对本页的请求次数。 另外,由于HiddenField控件也可以在浏览器中被客户端程序访问,因此可以用来充当服务器端和客户端的中间变量,在服务器C#程序和客户端Javascript程序之间交换数据。,例 52 查看ASP.NET的视图状态隐藏域。 在网站项目解决方案管理器中,右击网站根结点,选择“添加新项”,添加一个“Web窗体”,按F5调试运行项目,在IE8浏览器中,选择“页面”按钮下的“查看源文件”,可以看到如下页面HTML原始源代码: 分析:本例在服务器端只包含一个“空”页面,但ASP.NET生成的客户端网页代码中,自动产生了视图状态数据的隐藏域,value属性中的值是经过编码的,保存了本页面中ASP.NET认为需要“记忆”的数据。,例 53 查看视图状态隐藏域数据随着HTTP请求回发。 在例 52中的Web窗体页上,放上一个Button控件,修改其ID为“ButtonSubmit”,Text为“提交”,编写其Click事件委托函数如下:protected void ButtonSubmit_Click(object sender, EventArgs e) Request.SaveAs(“c:request.txt“, true); 在浏览器中查看本页面,按照例 52中的方法在浏览器中查看源文件,可看到自动生成的视图状态隐藏域标记: 再点击页面的“提交”按钮,然后打开C盘的request.txt文件,可以看到视图状态数据也被回发,相关数据如下:_VIEWSTATE=%2FwEPDwUKMTQ2OTkzNDMyMWRkmN60Y81Lx0LZIGBNhhmeMMu7oco%3D 分析: 比较例 52和例 53中的input标记,可以看到它们value属性不同,这是因为例 53中的Web窗体页多了一个Button按钮,所以视图状态数据不同。 “提交”按钮的Click事件委托函数,用Request对象的SaveAs方法,实现了将HTTP请求数据保存在C盘的request.txt文件中的功能。 比较例 53中源文件中的和回发请求中的视图状态数据,可以发现在回发请求中,分别用“%2F”、“%3D”代替了源数据中的“/”和“=”字符,这是HTTP协议所规定的,除此之外,回发前后的视图状态数据并未发生变化。,例 54 利用ASP.NET的HiddenField控件,使HTTP协议“记忆”上次请求的数据:使用Response.Write方法,显示当前是对本页面的第几次请求。 在项目中添加一个Web窗体页,放上一个HiddenField控件,修改其ID属性为“HiddenFieldRequestCounter”,修改其value属性为“0”,放上一个Button控件,修改其Text为“提交”。编写Page_Load事件委托函数如下:protected void Page_Load(object sender, EventArgs e) int 请求次数=Convert.ToInt32(HiddenFieldRequestCounter.Value); 请求次数=请求次数+1; HiddenFieldRequestCounter.Value=请求次数.ToString();
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号