Web应用程序
1.页面的C#代码(后台文件代码)一旦发生修改,需要手动重新编译(生成)一下,生成新的网站程序集(.dll),否则不会运行编写的新代码。
2.再次强调,不论是【网站】还是【网站应用程序】最终还是被编译成程序集使用的。
也就是说,我们所谓的【动态页面】(ashx/aspx)都是网站程序集里的类而已。
3.Web应用程序的每个页面类都会自动加上一个命名空间,而网站页面类不会。
WebForm(aspx)和一般处理程序(ashx)的区别
1.WebForm:分 aspx 和 aspx.cs 两个前后台文件,aspx主要用来当做“html模板”用,而aspx.cs就是页面处理代码。
2.一般处理程序:分ashx和 ashx.cs 两个文件,ashx里只有一个指令集,没有任何其他代码;ashx.cs就是页面处理代码。如果有大量html,需要通过ashx来拼接字符串或读取模板的方式完成。
3.WebForm类继承于 Page类;而一般处理程序类 实现于 IHttpHandler 接口。
但是,Page类实现了 IHttpHandler接口,所以,WebForm类也 实现了 这个接口。
练习:创建Web应用程序,创建一个输出服务器时间的 WebForm(aspx)。
4.为什么要使用WebForm(aspx)?
如果要输出大量的html代码的话,使用ashx直接输出html字符串会比较繁琐、读取模板又比较消耗时间和资源,所以当出现这种情况的时候,建议使用 WebForm。
5.什么情况下使用一般处理程序(ashx)?
当输出内容不包含大量的html甚至不输出html的时候,就可以使用 ashx(图片,json,xml)。
WebForm详解
1.页面类指令集(给【编译器】用)
<%@Page Language="C#" AutoEventWireup="true" CodeBehind="01FirstWebForm.aspx.cs" Inherits="_03WebForm._01FirstWebForm" %>
1.1 CodeBehind:指定对应的后台文件名称
1.2 Inherits:指定了前台类继承于哪个后台类。
(透露了一个小秘密:前台页面aspx也会被编译成一个类,前台类 -> 后台类 -> Page -> IHttpHandler)
2. Page 的源码
3.aspx后台类里直接访问 上下文属性
protected void Page_Load(object sender, EventArgs e) { //在webform中可以直接通过Page类的属性 访问到 当前请求上下文对象里对应的属性 //Response -> context.Response //Request -> context.Reqeust //Session -> context.Session }
【源码如图】
4.aspx后台类里的Page_Load方法执行:
//【Page_Load方法会被 Page类里的ProcessRequest调用】
//1.Page类的【事件自动注册机制】会自动的根据 后台类 里的【事件方法名】来找到 Page_Load方法,将此方法 注册到 Page 类一个 OnLoad事件(委托)中
//2.在页面被请求执行的时候,在11-12事件中间调用Page类的ProcessRequest方法
//里面就会 调用 这个Page的所谓的【页面生命周期】,其中就会调用 OnLoad事件从而 执行 注册在里面的 Page_Load方法
protected void Page_Load(object sender, EventArgs e) { Response.Write("我被ProcessRequest方法调用了"); }
5.后台向前台页面输出数据方式
5.1在Page_Load方法中执行Response.Write("<div>我要去前台咯~~</div>");
输出位置为:生成的HTML代码的最上面。
为什么输出在最上面?
因为Page类ProcessReqeust方法里微软写好的代码,已经定义了一大段叫做【页面生命周期】的代码,其中会先执行Load事件,此时就通过事件调用执行了 我们的后台类里写的 Page_Load方法;
在【页面生命周期】最后,调用 RenderControl方法,按照前台页面类的代码生成整个HTML页面;所以,Load里输出的在前,前台页面的在后。
5.2通过继承关系,在前台页面(子类)中指定位置访问后台页面类(父类)的非私有成员
注意:<%%>
6.页面的【事件自动注册机制】
在前台页面的@Page 指令集中有一个 AutoEventWireup="true" ,这个就是【事件自动注册机制】的开关,默认为打开。
当某个页面开启【事件自动注册机制】,那么被浏览器请求时,asp.net内部机制 会自动的创建被请求的前台页面类对象,同时,扫面后台页面类里的所有方法名,一旦找到 符合约定的 方法名,如:Page_Loade,就会将其自动添加到 Page类父类Control里的一个【对应的 事件委托 】中。
Request其他属性
1. UrlReferrer:请求的发起页面路径。【对应请求报文里的 Refer 属性】
如:在00Test.aspx页面 点击超链接去 02OutPutImg.ashx,产生报文如下:
在 02OutPutImg.ashx 页面中可以通过 Reqeust.UrlReferrer获取。
2.图片盗链:服务器B的输出给浏览器的页面中包含 服务器A的图片。
这样对于浏览器用户来说,只知道访问了服务器B的页面,但不知道图片是从服务器A输出的。
所以服务器A要防止别的服务器访问它的图片等其它资源。
【图例】
3. Request.UserHostAddress:获取浏览器的IP地址
注意:请求报文不包含此项数据,服务器通过Socket获取的。
Server常用成员
1.MapPath
2.Excute:服务器端包含主要用来在aspx页面上指定位置输出另一个aspx页面的运行结果。
【图例】
状态保持方案
1.客户端:Cookie,表单元素,Url(QueryString)
Cookie
概念:Cookie是一种能够让网站服务器把少量数据(4kb左右)储存到客户端的硬盘或内存,并且读取出来的一种技术
//1创建cookie对象,并存入键值对 HttpCookie cookie = new HttpCookie("aKey", strName); //2设置cookie2分钟之后失效 cookie.Expires = DateTime.Now.AddMinutes(2); //3设置cookie指定需要发送的文件夹 //如果浏览器访问 admin文件夹里的页面,则浏览器自动发送该cookie内容 //如果浏览器访问admin文件夹外面的页面,则浏览器不发送该cookie内容 cookie.Path = "/admin"; //补充:二级域名cookie //cookie.Domain ="111.baidu.com" //4将cookie写入响应报文对象 Response.Cookies.Add(cookie);
【图例】
2.服务端:Session,ApplicationObject,Caching,数据库
Session
1.概念:将数据储存在服务器端缓存中,并根据SessionId访问的一种数据储存机制。
【图例】
2.SessionID的传递方式:
默认使用【浏览器缓存Cookie】保存;
如果浏览器禁用了Cookie,则将SessionID放入Url中来传递。
3.特点:
a.保持【某个用户】的某些数据状态;其它用户访问不到他的数据;
b.让用户在使用浏览器访问本网站时可以在任意页面拿到Session中的数据;
c.保存在服务器端比较安全;
d.一旦用户关闭浏览器,则丢失了SessionID,那么服务器的Session数据将在默认时间后自动销毁。
注意:
一般处理程序中如果要访问Session就必须实现 IRequiresSessionState接口
而WebForm的前台页面类,在编译的时候,自动的加上了IRequiresSessionState接口
4.Session加载机制
在第8个事件创建完被请求的页面对象之后,也就是第9个事件中,asp.net机制会检测当前页面对象是否实现了System.Web.SessionState.IRequiresSessionState 接口
4.1如果实现了,则:获取请求报文里存在cookie中的 SessionId,然后到服务端的Session池里去找,找到对应的Session对象,并把引用交给当前请求上下文的Session属性。
4.2如果没有实现,则不去加载Session属性。
5.ViewState
5.1使用前提,只能使用在WebForm中,并且前台页面必须 包含一个 runat=server的表单。
6.Application
概念:就是存在服务器端的一个公共的键值对集合,为了避免脏读,使用之前一定记得 加锁,用完后记得解锁。