asp.net笔记

1、 复习

a) WebForm前后台页面(aspx, aspx.cs)文件在被访问时,会被编译成类,前台类继承于后台类

b) 被访问时,服务器会创建【前台页面类】对象来 作为处理浏览器请求的对象

c) 前台类对象时如何结合后台类的方法,生成整个页面的HTML代码的呢?---被请求时,生成页面控件对象树(在执行PR方法时,才创建控件树),控件树负责组织整个页面的内容(_BuildControlTree()---生成控件树方法)

d) 继承关系:前台页面类->后台页面类-> Page-> TemplateControl -> Control(包含ControlCollection集合,用来保存子控件)

e) 对于ASP.NET来说,动态页面aspx或ashx被浏览器请求时,都是作为类的对象来运行;而不是像处理静态页面html或jpg一样,直接读取文件里的内容

f) WebForm中每次页面被请求的时候都会调用Page_Load()方法,类型ashx中的PR方法

2、 Request其他成员

l Request.UrlReferrer 请求的来源,可判断从百度搜的哪个关键词、防下载/图片盗链,可以伪造(比如迅雷)。全局防盗链 用Globals.asax

l 盗链:自己服务器的内容,被别的服务器盗用,显示在别人的网页上(即访问A服务器页面的内容时,通过超链接可以直接访问B服务器中的内容)

l 解决办法:

1) 服务器自动根据图片名称和当前这次请求的时间来产生一个钥(密文),接收到请求报文后,服务器算出图片请求的时间,然后再拿这个时间和当前服务器时间进行比较,如果时间超过了1分钟,则不返回图片内容

2) 使用公钥:在图片数据中添加一个公钥,在请求的时候解析就行

l Request.UserHostAddress获得访问者的IP地址

l Request.Cookies 获取浏览器发过来的浏览器端的Cookie

读取Cookie值: Request.Cookies["mysessionid"]

写入Cookie值:Response.Cookies.Add(HttpCookie cookie)

l Request.MapPath(virtulPath)将虚拟路径转换为磁盘上的物理路径,

Request.MapPath("~/a/b.aspx")就会得到D:\2008\WebSites\WebSite4\a\b.aspx

当用户字List.aspx页面上点击超链接时,浏览器生成的请求报文中多出了一个属性:(代表当前点击超链接的页面路径):Referer:http://localhost:1256/WebForm/List.aspx

补充:

1、 Request.AppRelativeCurrentExecutionFilePath,获取当前执行请求相对于应用根目录的虚拟路径,以~开头,比如“~/Handler.ashx”,

2、 Request.PhysicalApplicationPath,获取当前应用的物理路径,比如D:\我的文档\Visual Studio 2008\WebSites\WebSite4\

3、 Request.PhysicalPath,获取当前请求的物理路径,比如D:\我的文档\Visual Studio 2008\WebSites\WebSite4\Handler.ashx

4、 Request.RawUrl获得原始请求URL、Request.Url获得请求的URL,区别涉及到URL重写的问题

5、 Request.UserLanguages获得访问者浏览器支持的语言,可以通过这个实现对不同语言的人显示不同语言的页面。

3、 Response其他成员

响应的缓冲输出:

为了提高服务器的性能,ASP.Net向浏览器Write的时候默认并不会每Write一次都会立即输出到浏览器,而是会缓存数据,到合适的时机或者响应结束才会将缓冲区中的数据一起发送到浏览器。

Response对象的主要成员:

1、 Response.Buffer、Response.BufferOutput:是否采用响应缓存,默认为true。经过Reflector反编译,发现两个属性是一样的,Buffer内部就是调用的BufferOutput。

2、 Response.Flush():将Response缓存区中的数据立即输出到浏览器。案例:大批量数据的导入,显示正在导入第*条数据,用Thread.Sleep模拟耗时。

3、 Response.Clear():清空缓存区中的数据,这样缓存区中没有发送到浏览器端的数据不会被发送到浏览器。

4、 Response.ContentEncoding输出流的编码。

Response.ContentEncoding = System.Text.Encoding.Unicode

5、 Response.ContentTypResponse.ContentEncodinge 输出流的内容类型,比如是html(text/html)还是普通文本(text/plain)还是JPEG图片(image/JPEG)。

6、 Response.Cookies 返回给浏览器的Cookie的集合,可以通过它设置Cookie

7、 Response.OutputStream 输出流,在输出图片、Excel文件等非文本内容的时候要使用它

8、 Response.End() 终止响应,将之前缓存中的数据发给浏览器,End()之后的代码停止执行,End方法里调用了Flush()方法。可以用在终止一些非法请求的时候,比如盗链等

9、 Response.Redirect(url) 重定向浏览器到新的网址(站外网址或站内网址)。

Response.Redirect("http://www.rupeng.com")、Response.Redirect("a.htm")。

重 定向的过程经历了服务器通知浏览器“请重新访问url这个网址”和浏览器接到命令访问新网址的过程。使用HttpWatch查看整个响应过程的Http报 文。用Redirect因为是浏览器自己去重新访问新网址的,所以在地址栏中是可以看到网址的变化的。后面会用来防止刷新浏览器时提示“重试”。

10、 Response.SetCookie(HttpCookie cookie),向输出流中更新写到浏览器中的Cookie,如果存在就更新不存在就增加。是对Response.Cookies的简化调用。

11、 Response.Write()向浏览器输出内容。

4、 Server(HttpServerUtility)

l Server是上下文对象context的一个属性,是HttpServerUtility类的一个对象(实例),它提供对服务器上的方法和属性的访问

l Server对象的常用方法

1) MapPath(string path)方法,获得文件的物理路径

2) Execute方法和Transfer方法,执行另一个页面的脚本

a) Execute(string path),访问重定向的页面,并将其内容放在Response的缓存区中,再执行重定向语句之后的代码,最后输出

b) Transfer(string path),终止当前页的执行,开始指定路径的新页。(内部重定向请求,在服务器端执行另一个页面,并将执行的结果返回到浏览器)

因为是内部接管,所以在被重定向到的页面中是可以访问到Request、Cookies等这些来源页面接受的参数的,就像这些参数是传递给他的,而Redirect则不行,因为是让浏览器去访问的。

注意:

i. Transfer方法之后的代码都不运行了

ii. Transfer是内部接管,因此不能像Redirect那样重定向到外部网站。

iii. 不能直接重定向到ashx,否则会报错“执行子请求出错”

3) HtmlEncode方法和HtmlDecode方法

a) HtmlEncode(string s)方法,对字符串进行HTML编码,并返回已编码的字符串

b) HtmlDecode(string s)方法,对HTML编码的字符串进行解码,并返回解码后的字符串

4) UrlEncode方法和UrlDecode方法,URL编码和解码

a) UrlEncode(string s )方法,对字符串进行URL编码,并返回已编码的字符串。用于处理超链接中的中文问题

b) UrlDecode(string s)方法,对URL编码的字符串进行解码,并返回解码后的字符串。

注意:

HtmlDecode()、 HtmlEncode() 、UrlEncode()、UrlDecode()是对HttpUtility类中相应方法的一个代理调用。推荐总是使用HttpUtility,因为有 的地方很难拿到Server对象,而且Server的存在是为以前ASP程序员习惯而留的。推荐用HttpUtility.HtmlEncode。

l 有的时候不能拿到HttpContext对象,比如在Global.asax中(后面讲),可以通过HttpContext.Current拿到当前的HttpContext,进而拿到Response/Request/Server等

5、 无状态的Http(即服务器不记得上次给了浏览器什么

无状态的根本原因是:

浏览器和服务器使用Socket通信,服务器将请求结果返回给浏览器后,会关闭当前Socket连接。而且服务器会在处理页面完毕后销毁页面对象。

应用层面的原因是:浏览器和服务器之间通信都遵守HTTP协议。

不要将状态信息保存到类变量中的原因:

一个浏览者发出的请求都是由实现了IHttpHandler接口的对象进行响应,由于下次访问不一定还是上次那个对象进行响应,上次响应完毕对象可能已经被销毁了,写的类变量值早就不存在了。

l 对网站造成的影响:如果用户录入了一些信息,当跳转到下一个页面时,数据丢失,再也不能获得那些数据。

解决办法(把状态信息记录在某个地方):

a.服务器端

b.浏览器端

c. 表单元素中,如:隐藏域<input type=“hidden”/>(Http报文)

l 为什么 aspx和一般处理程序 都必须实现 IHttpHandler接口?因为服务器不知道用户会编写什么样的类,类里面会编写什么方法;所以微软就规定,凡是可以被外部请求访问的类,必须实现 IHttpHandler接口;一旦用户编写的类实现了此接口,就一定会包含接口中的ProcessRequest方法,那么服务器就可以统一调用了。

代码示例:

http://www.oumind.com/index.aspx

object o=.......服务器根据用户请求的路径反射出用户请求的页面类的对象(index_aspx,此类一定已经实现了IHttpHandler接口)。

IHttpHandler h = (IHttpHandler)o;

h.ProcessRequest();

6、 ASP.NET中的状态(信息)保持方案11:31

1) 客户端的状态保持方案:

ViewState、隐藏域(Hidden Field)、Cookies、控件状态(Control State)、URL查询参数(QueryString)

本质上3种:隐藏域/Cookies/QueryString(url?name=1)

2) 服务端的状态保持方案:

Session(会话)、Application(Object)、Caching(缓存)、DataBase(数据库)

常用的状态(信息)保持方式(重点)

l ViewState

ASP.NET 的 .aspx页面特有,页面级的;即在页面上的一个隐藏域中保存客户端单独使用的数据的一种方式;

保存数据方式(键值对):

ViewState["myKey"]="MyData";等同于ViewState.Add(“myKey”, “MyData”);

读取数据方式:

String myData;

if(ViewState["myKey"]!=null)

{

myData=(string)ViewState["myKey"];

}

l 服务器端控件的值都自动保存在ViewState中,而且ViewState不能存储所有的数据类型,仅支持:String、Integer、Boolean、Array、ArrayList、Hashtable

l 使用前提:页面上必须有一个runat=Server的表单

l 服务器在接收到用户请求一个页面后,会自动在请求报文中找看是否包含__VIEWSTATE的隐藏域,如果有,则将中间的值解码后添加到页面的ViewState属性中。

l 服务器在输出的时候,也会自动的将ViewState中的值添加到表单里名叫__VIEWSTATE的隐藏域中。

l VIEWSTATE适用于同一个页面在不关闭的情况下多次与服务器交互

l 跨页面提交的__VIEWSTATE不会被目标页面装入页面的ViewState属性中

缺点

1) 加大网站的流量

2) 降低访问速度

3) 机密数据放到表单中会有数据欺骗等安全性问题。

隐藏域还是存在,只是不保存服务器端控件的属性和值:EnableViewState=false(禁用)

ViewState里主要保存:服务器端控件的属性值,用户定义的ViewState键值对 14:30

1) 页面的ViewState属性实际上就是获取了浏览器提交过来的一个名为_VIEWSTATE的隐藏域中的值

2) 在页面类对象,执行PR方法的时候,先创建了控件树,然后通过执行LoadState方法,将请求报文中的名字为__VIEWSTATE的值,然后反 base64编号,进行反序列化, 最终还原成集合,然后将其中属于程序员自己(11::56还包含服务器端运行空间的数据和状态???)添加到ViewState里的键值对还原到页面对象 的ViewState属性中。然后才执行的Page_load方法。

注意:

l Cookie

HTTP协议下的一种方式,通过该方式,服务器或脚本能够在客户机上维护状态信息;

就是在客户端保存客户端单独使用的数据的一种方式;

就像你的病历本一样,医院直接给你带回家;

l Session和进程相关(现在指的是进程内的Session)。

在服务器端保存客户端单独使用的数据的一种方式;

就像银行账户,钱都存在银行里,你就拿一张银行卡(SessionId)回家;

l Application

在服务器端保存共享数据的一种方式;

就像银行的单人公共卫生间,谁进去都行,但一次去一个,进去了就锁上门,出来再把锁打开;

7、 Aspx里的ViewState初探(重点,常考)

查 看生成的源代码,ASP.Net将所有隐藏内容统一放到了名字为__VIEWSTATE的隐藏字段中,使用序列化算法将所有隐藏内容放到一个字符串中。点 击几次在使用ViewStateDecoder这个工具查看ViewState内容,发现了确实将这些改变的内容放到了ViewState中。存储非表单 域、非value值的容器。

禁用ViewState的方法

1)禁用单个控件:设定属性enableviewstate="false",

禁用ViewState以后TextBox版本不受影响,Div版本受影响,因为input的value不依靠ViewState。

2)禁用整个页面的,在aspx的Page指令区加上EnableViewState="false" 。内网系统、互联网的后台可以尽情的用ViewState。

回答ViewState原理的时候:说Input版本(TextBox)自增和Div版本(Label)的不同。(完美!!!)-- 当某些控件的某些属性不属于浏览器表单的提交范围时,fw将会把这些属性添加到ViewState中保存。

WebForm 的IsPostBack(回传,bool类型)依赖于ViewState。只要浏览器提交的请求报文中包含__VIEWSTATE这个键,ASP.NET 就会将页面的IsPostBack属性设置为true。(不管是通过地址栏提交的还是超链接或者点击按钮提交的,只要有__VIEWSTATE这个键,服 务器就将IsPostBack设置为true)

8、 Cookie(小甜饼)—病历本

l Cookie是一种能够让网站服务器把少量数据(4kb左右)储存到客户端硬盘或内存,并且读取出来的一种技术。

l 当你浏览某网站时,由Web服务器放置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、浏览过的网页或者停留的时间等网站想要你保存的信息。当你再次通过浏览器访问该网站时,浏览器会自动将属于该网站的Cookie发送到服务器去,服务器通过读取Cookie,得知你的相关信息,就可以做出相应的动作。

如在页面显示欢迎你的标语,或者让你不用输入ID、密码就直接登录等等。

l 浏览器访问一个站点时,只将属于当前站点的Cookie发过到服务器。(根据域名)

l Cookie储存在客户端,不兼容浏览器!

l 最好是将要保存的内容在服务器端加密,为什么?

l 在硬盘中存放的位置与使用的操作系统和浏览器密切相关。

l 浏览器保存Cookie有两种方式:

1—浏览器的内存中;

2—浏览器所在的电脑的硬盘中。

l DateTime Expires属性,为Cookie对象设置失效时间:

cook.Expires = DateTime.Now.AddMinutes(5);//设置cook5分钟后失效

开发场景:常用于登录和保存用户最近浏览商品

Cookie的Expires属性不可读.(只有在向浏览器写出的时候能设置)

Cookie的操作

l 服务器设置Cookie:

HttpCookie cok = new HttpCookie(“uId”, “10001”);//(“键”,”值”)

cok.Expires = DateTime.Now.AddDays(18);//设置失效日期-现在之后的18天后

context.Response.Cookies.Add(cok); //添加到响应中

l 服务器获得客户端传来的Cookie:

string strUName=context.Request.Cookies[“uId”].Value;//从请求中获得Cookie

Cookie原理---具体如何往返的?

1) 普通get请求没有Cookie

2) 服务器通过响应报文头里的set-cookie向浏览器设置Cookie信息

3) 浏览器通过请求报文头里的Cookie传递浏览器存储的Cookie信息

服务器向浏览器写出Cookie实际上就是在 响应报文中 生成响应行:

* Set-Cookie: uinfo2=123; expires=Mon, 06-Jun-2011 06:48:47 GMT; path=/

* 浏览器读取此 响应行后 会自动在客户端硬盘中产生一个Cookie文件,名为:

* Cookie:administrator@localhost/,注意@后的 localhoust/ ,实际上是颁发此Cookie网站的域名;

* 当浏览器下次再访问此域名时,就会自动将 后缀为 localhoust/ 的cookie文件内容发送到服务器。

1) cookie.Path(为指定的文件夹生成Cookie)

2) cookie.Domain (域/域名) www.oumind.com book.oumind.com

3) Response.Cookies和Request.Cookies中间的关系 – 有共用部分

4) Cookie在浏览器硬盘的存储位置:

C:\Documents and Settings\登录帐户名\Cookies

可以通过 开始-运行-cookies 自动打开。

补充:

不同浏览器间cookie允许的总大小(包括名(name)、值(value)和等号):

Firefox和Safari cookie---------多达4097个字节

Opera------------多达4096个字节

IE----------多达4095个字节

浏览器允许每个域名所包含的cookie数:

Microsoft指出IE8增加cookie限制为每个域名50个,但IE7似乎也允许每个域名50个cookie。

Firefox每个域名cookie限制为50个。

Opera每个域名cookie限制为30个。

Safari/WebKit貌似没有cookie限制。但是如果cookie很多,则会使header大小超过服务器的处理的限制,会导致错误发生。

注:“每个域名cookie限制为20个”将不再正确!

当很多的cookie被设置,浏览器如何去响应。

除Safari(可以设置全部cookie,不管数量多少),有两个方法:

最少最近使用(leastrecentlyused(LRU))的方法:当Cookie已达到限额,自动踢除最老的Cookie,以使给最新的Cookie一些空间。InternetExplorer和Opera使用此方法。

Firefox很独特:虽然最后的设置的Cookie始终保留,但似乎随机决定哪些cookie被保留。似乎没有任何计划(建议:在Firefox中不要超过Cookie限制)。

9、Session(HttpSessionState

Session提供了一种把信息保存在服务器内存中的一种方式。它能存储各种数据类型包括自定义对象。开发场景:常用于保存登录用户ID

使用

赋值:Session[“uName”]=”SXL”;

取值:string strName=Session[“uName”].ToString();

销毁(取消、退出):Session.Abandon();//销毁服务器端的Session对象

Session.Clear();//清空服务端的Session对象里的键值对

在服务器端创建一个键值对为uId=strId的Session对象,并存入了服务器端的Session池中,再从Session池中获得了访问该Session对象的id号

Session常用属性、方法

SessionId:唯一用户会话标识符

TimeOut:用户超时(单位:分钟),默认为20分钟

Count:会话状态集合中的项目数

Abandon方法:用于显示结束会话

注意:

1) 在整个用户会话过程中都会保留此信息。但当会话过期或终止时,服务器就会清除 Session 对象

2) Session 对象用于存储有关用户的信息。每个客户端的Session是独立存储,用户不能访问或修改他人的Session 。Session只可由该会话的用户访问(因为SessionId的东东以cookie的方式保存访问者浏览器的缓存里了)

3) 当用户在应用程序中从一个网页浏览到另一个网页时,存储在 Session 对象中的变量不会被丢弃。

16:40

Cookie与Session保存机制

在HttpApplication请求管道第9个事件的时候,根据浏览器发来的SessionId自动从Session池中读取SessionId对应的Session对象,并赋值给当前页面对象的Session属性

如果浏览器禁用了Cookie的话,服务器也可以通过SessionId保存在url中来完成SessionId在浏览器和服务器端间的传递(需要设置配置文件里的sessionState节点的cookieless=”AutoDetect”)

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319下的aspnet_isapi.dll