ASP.NET 总结

本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看。

一、Socket 就是两个程序通讯用的

一台计算机上的端口有65536个(1~65535)http:80端口、FTP:21端口、SMTP:23端口Socket一般应用模式(服务端和客户端)

服务器端的Socket(至少需要两个)

1、一个负责接收客户端的连接请求(不负责与客户端通信)2、每成功接收到一个客户端的连接便在服务端上产生一个对应的Socket(负责与客户端通信)

客户端的Socket必须指定要连接的服务端地址和端口,连接成功后,负责与服务端的对应的Socket进行通信工作

socket.Sent() 如果有两个连续的发送,可以认为是一起发送的,因为两者发送的时间间隔很短,只有20ms左右。


二、WebApplication(Web应用程序)和WebSite(网站)的区别

WebSite是为了兼容从ASP转过来的开发人员的习惯而存在的,用起来比较简单,1、不需要命名空间。2、“CS代码”修改以后不需要重启就能看到变化,但是不利于工程化开发, 比如代码出错不容易发现,代码不分命名空间。3、生成的dll文件的路径不是在bin中,但通过反射可以迅速找到其路径。

(Reponse.Write(this.GetType().Assembly.Location))讲简单基础知识时用WebSite;讲高级技术和做项目的时候用WebApplication 


三、form 提交method (Get, Post 的区别,默认是Get)

1)get是通过url传递表单值,post传递的表单值是隐藏在http报文中的,url中看不到

2)get传递的数据量是有限的,post没有限制(post可以用来上传文章type=“file”,传递密码type=“password”,发表大段文章<textarea>)

3)post在刷新时会有提示重新提交表单的问题,确定的话,就相当于再次进行了post提交(但重新敲地址栏就是get提交了) 


四、http响应码

200:ok

301:Moved Permanently---永久转移

302:Found---重定向

307:Temporary Redirect

400:Bad Request---错误的请求(服务器不认---发出错误的不符合http协议的请求)

401:Unauthorized---未认证(一般需要用户名、密码才能登陆)

403:Forbidden---禁止访问(访问权限等)

404:Not Found---没有找到

500:Internal Server Error---服务器内部错误

503:Service Unavailable---访问人数过多 


五、报文

【1】http请求报文

1)用httpwatch查看访问一个网站的响应情况,敲入一个网址后,浏览器向服务器发出请求。页面中的html、图片、js、css在单独的请求中。网页加载时是一一响应的。

2)get .....aspx http1.1表示向服务器用get方式请求首页,使用http1.1协议。

3)Accept-Encoding gzip,deflate表示浏览器支持gzip,deflate两种压缩算法。

4)Accept-Language zh-cn表示浏览器支持的语言,很多进入后自动就是中文界面的国际网站就是通过读取这个头的值实现的。

5)Connection keep-Alive(长连接 服务器响应之后 等待很短的时间,当很短的时间内没有人连接才断开) 一般情况下,一旦web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了Connection keep-Alive,则TCP连接在发送后将任然保持打开状态,于是,浏览器可以继续通过相同的连接 发送请求。保持连接节省了每个请求建立新连接所需的时间,还节约了网络带宽。(短连接 服务器响应之后 立即断开连接)

6)Cookie是浏览器向服务器发送和当前网站关联的Cookie,这样在服务端也能读取浏览的Cookie了,一般可以把sessionId放在其中传递给服务器,从而取到对应session值。

7)User-Agent为浏览器的版本信息。通过这个信息可以读取浏览器是IE还是FireFox、支持的插件、Net版本等。结构图如下:

【2】服务器返回的报文
1)Server:Cassini/3.5.0.5表示服务器的类型

2)Content-Type:text/html;charset=utf-8表示返回数据的类型

3)服务器是通过Content-Type告诉客户端响应的数据的类型,这样浏览器就根据返回数据的类型来进行不同的处理,如果是图片类型就显示图片,如果是文本类型就直接显示内容,如果用html类型就用浏览器显示内容,如果是下载类型就弹出下载工具等。常用Content-Type:text/HTML,image/JPEG,text/plain,text/javascript,application/x -excel,application/octet-stream(二进制文件)

4)Content-Length表示后续数据消息体的长度,报文头只是描述,返回的具体数据(比如HTML文本、图片数据等)在两个回车之后的内容。
结构图如下: 

 


六、Web开发的基本原则

1)最小权限原则。只允许用户做***,而不是不允许用户做***

2)能在客户端完成的事情,尽量不要在服务端实现。
3)客户端验证不能代替服务端验证, 客户端校验是为了很好的客户体验(避免一校验就刷新页面),服务端校验是最后一次把关,防止恶意破坏浏览器查看的是服务端代码的执行输出文本,看不到aspx的源代码。

C#代码是运行在服务器端,JS是运行在客户端的。 


七、Response 和 Request

Request的方法:

1、获得post数据:context.Request.Form["txtName"];

2、获得get数据: context.Request.QueryString["txtName"];

一般不使用context.Request.Params["txtName"] 和 context.Request["txtName"] 这两种方法第一种要进行遍历,第二种使用的是索引,效率不高,用上面两种形式就可以了。

Response的方法:

Write()响应的缓存输出:为了提高服务器的性能,ASP.NET向浏览器Write的时候默认并不会每write一次都会立即输出到浏览器,而是会缓存数据,到合适的时机或者响应结束才会将数据一起发送到浏览器。Flush()将缓存区数据立即发送给浏览器,这在需要将write出来的数据立即输出到浏览器的场合非常适用。案例:大批量数据的导入,显示正在导入第几条,用Thread.Sleep模拟耗时。End()结束输出(并将缓冲区中的内容输出到客户端)
Redirect()重定向 


八、一般处理程序

一般处理程序实现了IHttpHandler接口,而这个接口中包含了
ProcessRequest(HttpContext context)这个方法,HttpContext即指上下文,即对请求和响应都可以在实现的类中完成,只有实现了这个接口的类才能接受浏览器的请求!

一般处理程序执行的大致步骤(以数字自增为例)? 

public void ProcessRequest (HttpContext context) {
	context.Response.ContentType = "text/html"; 
	//1、读取html中的内容(这里读取的永远是那个模板里面的值) 
	string html = context.Request.MapPath("div数字自增.htm"); 
	html = System.IO.File.ReadAllText(html);
	//设置初始值为0
	int i=0;
	string _viewstate = context.Request.Form["_viewstate"]; 
	//3、不是首次进入页面(点击按钮post提交过来的)
	if (!string.IsNullOrEmpty(_viewstate))
	{
		//post是将浏览器端输入的值提交过来的
		string num = context.Request.Form["getnum"]; 
		i = Convert.ToInt32(num)+1;
	} 
	//2、不管是首次进入还是post提交过来的,都进行替换工作 
	html = html.Replace("@value", i.ToString()); 
	//在页面上显示最终的结果 
	context.Response.Write(html);
}

模板:

<form action="div数字自增.ashx" method="post">
<input type="hidden" name="_viewstate" value="aa" /> 
<input type="hidden" name="getnum" value="@value" /> 
<div>@value</div>
<input type="submit" name="name" value="提交" />
</form>

1、用户首次通过敲地址栏访问,服务端就读取实现在服务端准备好的模板页,并将结果返回给客户端,此时客户端显示0
2、客户端点击"提交"按钮进行自增操作,此时是post提交过来的,服务端发现_viewstate的值不为空,就进行了num数字加1操作,然后将结果1返回给浏览器3、当客户端继续点击"提交"按钮,由于浏览器上的数字是服务端响应返回的数值1,因此此时提交的是1,然后进行如2的步骤操作,完成自增操作。

为什么要这么折腾的进行操作?? 是因为服务端是无状态的,不会"记住"上次发生了什么,所以将值保存在隐藏字段中! 



九、其他一些知识点

1. 127.0.0.1是回环地址(LoopBack),就是表示访问本机,localhost就是127.0.0.1别名,是无法在外部访问的,连本机IP也访问不了。0.0.0.0任意IP(AnyIP),不用写死绑定的IP了,通过任何一块网卡都可以访问网络程序。

2. http为什么是无状态的?为什么要断开连接?

因为服务器响应之后,就很快会断开连接了;减小服务器压力

3. ASP.NET后台做的事情:存储数据、访问数据库、复杂的业务逻辑运算、安全性要求高的运算。

如果设置了控件的disabled属性为true,即使控件有name及value属性,也提交不到服务端

Request.UserHostAddress获得访问者的IP,通过这个可以限定提交次数。


 十、enctype的说明

<form action="上传图片.ashx" method="post" enctype="multipart/form-data"></form>默认情况下enctype的值为application/x-www-form-urlencoded,可以不写。这种情况,报文的发送字符串是以"&"连接的,但遇到上传文件,这样写就不合理了,因为文件编码后,内部字符串也有可能是以&连接的,就混乱了,此时enctype应该设置为multipart/form-data,它的实现是随机生成很多横线加一数字字符串的格式,这样各个条件之间就可以分开了。 


十一、全局处理程序(写在App_Code文件夹中的cs文件)

其受aspnet_filter.dll的保护,客户端是无法直接访问的。

使用方法:在使用之前,先在配置文件中的<httpHandlers>节点进行如下的配置工作

<add verb="*" path="images/*.jpg" type="ImageHandler"/>它表示想要进行对images文件夹下的jpg文件进行直接处理,必须先经过ImageHandler.cs的操作。比如:用户想直接通过输入网址,直接访问图片,而网站的要求是必须先点击小图链接进来才可以访问的,这时候就可以提示用户不可以访问。而对于服务端其他的处理程序就可以直接进行对images文件夹下jpg图片的处理,不需要经过ImageHandler.cs的操作。

aspnet_filter.dll的两个作用

1 保护目录(App_Code, App_Data 等,里面的类不能被直接访问)

2 在禁用cookie的情况下,从url中获取sessionId 并且把请求转向到真实的文件 


十二、关于几个url

<a href="url.ashx">点击</a>

设置这个htm文件的路径为 http://localhost:1093/asp.net练习/关于url/url.htm

url.ashx这个文件的路径为 http://localhost:1093/asp.net练习/关于url/url.ashx

context.Response.Write(context.Request.RawUrl + "<br />");context.Response.Write(context.Request.Url+"<br />");context.Response.Write(context.Request.UrlReferrer + "<br />");三者的输出结果为:

RawUrl表示被访问文件的相对路径

/asp.net练习/关于url/url.ashx

Url表示被访问文件的全路径

http://localhost:1093/asp.net练习/关于url/url.ashx

UrlReferrer表示被访问文件请求页面的路径

http://localhost:1093/asp.net练习/关于url/url.htm 


十三、 图片水印的问题

当把水印效果的程序发布到IIS上的时候,是看不出水印效果的,因为图片是静态页面,客户端请求的时候,IIS服务器发现其是静态页面,直接将图片返回给浏览器,而对图片进行水印处理的程序还没有来得及进行处理。为解决这个问题,应该手动配置一下IIS,即在映射表中增加图片的映射,即.jpg--aspnet_isapi.dll. 


十四、Application(全局文件global.asax)

UrlReferrer作用:防下载盗链、防图片盗链,但是现在可以被伪造了(迅雷就是盗用的)。如果直接访问本网站的图片地址或者别的网站用a标签访问你图片的地址,UrlReferrer就是null,如果是嵌入到别的网页中(本网站中)的请求,UrlReferrer就是页面的地址。 

void Application_BeginRequest(object sender, EventArgs e) 
{
	Response.ContentType = "image/jpeg"; 
	//请求的是图片(防盗链处理)
	if (Request.RawUrl.ToLower().Contains("images/")) {
		//盗链过来的,则输出防盗链图片
		if (Request.UrlReferrer == null || !CheckTheSame(Request.UrlReferrer, Request.Url)) 
		{
			string path = Request.MapPath("~/盗链图片.png"); Response.WriteFile(path);
			Response.End();
		}
	} 
}
//判断本次请求与上次请求是否是同一个域名及端口号
bool CheckTheSame(Uri uri1,Uri uri2) 
{
	return Uri.Compare(uri1, uri2, UriComponents.HostAndPort, UriFormat.SafeUnescaped, StringComparison.CurrentCultureIgnoreCase) == 0;
}

十五、html中的相对路径

/ html中的根路径 不管有没有虚拟目录都返回http://localhost/daolian.jpg, 即看不到虚拟目录

./ 或者不写 指当前目录
../ 上一级目录
asp.net中的根路径(要有runat="server")

~/ 如果有虚拟目录返回http://localhost/Webform/daolian.jpg

如果没有虚拟目录返回http://localhost/daolian.jpg 


十六、Server对象

Server.MapPath就是调用Request.MapPathServer的UrlEncode、UrlDecode、HtmlEncode、HtmlDecode方法,以后直接用HttpUtility的这些方法使用就可以了!

因为有的地方很难拿到Server这个对象。 


十七、在C#代码中输出JS脚本的两种方式

1、脚本输出的位置 form表单结束标签之前Page.ClientScript.RegisterStartupScript(this.GetType(),"name","alert('内容')",true);

2、脚本输出的位置 form表单开始标签之后Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "name", "alert('内容')", true); 


十八、Response.Redirect()、Server.Transfer()、Server.Execute()之间的区别?

Response.Redirect 是有浏览器参与的(浏览器经过了多次请求),所以在地址栏中可以看到地址的变化。

Server.Transfer 与Server.Execute()是服务器内部的转接,浏览器请求了一次,浏览器不知晓,故地址栏中看不出url的变化,而两者的区别是: 

Server.Transfer在内部转接后,直接由最后一个接受的地址,返回数据给浏览器,

而 Server.Execute()是最后一个接受的地址处理完毕数据后,依次返回,再由刚开始浏览器请求的地址将数据返回给浏览器。 


十九、ASP.NET常用的状态保持方式(前两种客户端,后两种服务端)

ViewState、Cookie、Session、Application

1.  ViewState(就是在页面的一个隐藏域[它是由服务端生成并输入到客户端的]中保存客户端数据,然后通过这个隐藏域将内容提交给服务端。)

非表单元素无法将客户端的元素值传递给服务器端,即使是表单元素也只能传递value值,对于其他属性值比如颜色、大小等也是无法传递的,因此对于这些值都要存在隐藏字段中,这就是ASP.NET中ViewState的实现原理。禁用ViewState的 

方法:设置EnableViewState=“flase”.内网系统,互联网的后台可以尽情的用ViewState。Http协议是无状态的,不会记得上次和网页“发生了什么”,状态信息保存在隐藏字段中的缺点:加大网站的流量、降低访问速度、机密数据放到表单中会有数据欺骗等安全问题。

ViewState作用:将浏览器中的内容提交给服务器,让服务器记起“上次”在干什么,如果禁用则没有反应了,但在服务端赋值是可以的。它适用于同一个页面在不关闭的情况下多次与服务器交互。<!--ViewState对于需要PostBack处理的页面才可能用,对于新闻展示页面(不需要用户交互)完全没有必要用ViewState。禁用页面的ViewState并没有完全去掉ViewState,只要ViewState不是很大就可以了,如果要求一点ViewState都没有,那么在页面中就不能有runat=“server”的form,但禁用,很多的服务端就用不了了,所以不提倡这种做法。-->

例子:(假设Label1.Text初始值为10)//禁用了ViewState就读不到上次客户端的值,也就是在隐藏字段里面不接受用户提交过来的值,只读取服务端的默认值(点提交按钮,结果永远是10,50;但如果没有禁用,首次进来是10,50;但以后提交就永远是50,50了)

Response.Write("Label1的值是:"+Label1.Text+"<br/>");Label1.Text = "50";//即使禁用ViewState,在请求没有结束之前,也能读出来设置的值Response.Write("Label1的值是:"+Label1.Text+"<br/>");

面试举例:webform下div,input数字自增的区别:div版本的值存到了ViewState中,TextBox版本的不用存,因为TextBox就属于input,自己会提交给服务器,不需要隐藏字段。对于div自增,在自增过程中,如数字变为5的时候,自己将其篡改为10,再点击自增按钮,会显示6对于input自增,在自增过程中,如数字变为5的时候,自己将其篡改为10,再点击自增按钮,会显示11

2.  Cookie:就是存储在浏览器里的一些数据(以文本信息存储)。Cookie在服务端和客户端都可以存在!客户端向服务器提交时,除了传递普通的name字段的值,也会提交Cookie;服务器返回数据除了普通的html数据以外,还会返回修改的Cookie,浏览器把拿到的Cookie值更新本地浏览器的Cookie就可以。

互联网优化:图片服务器和主站域名不一样,降低Cookie流量的传输。

Cookie应用:打开页面时自动填上用户名,网页换肤。

存储Cookie的方式:

1、存储在内存中(关闭网页就没有了)2、存储在硬盘中(设置了Expires属性。关闭网页,在限定时间内,它被保存在硬盘中)

Cookie的几个特征:

1、Cookie是与域名相关的,所以163.com是不能读取baidu.com记录的Cookie。

2、一个域名能写入的Cookie尺寸是有限制的(4k左右),能写入的Cookie总条数一般是几十条。

3、Cookie不是写入以后一定下次能读出来的,浏览器可能会定期清除,用户也可能手动清除。

Cookie用法(客户端的操作方式)设置值:$.cookie("名字","值");一般应该设置有效期限:$.cookie("名字","值",{ expires: 10 });读取值:var v=$.cookie("名字");

Example:网页换肤

<html xmlns="http://www.w3.org/1999/xhtml"> <head>
<title></title>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> 
<script src="Scripts/jquery.cookie.js" type="text/javascript"></script> 
<script type="text/javascript">
	$(function () {
		var color = $.cookie('color'); if (color) {
			$('body').css('background', color); 
		}
		$(':button').click(function () { 
			$('body').css('background', $(this).val());
			$.cookie('color', $(this).val(), { expires: 10 }); 
		});
    });
</script>
</head>
<body>
	<input type="button" name="name" value="red" /> 
	<input type="button" name="name" value="green" /> 
	<input type="button" name="name" value="blue" />
</body>
</html>

cookie用法(服务端的操作方式) 

//赋值
protected void Button1_Click(object sender, EventArgs e)
{
	//自定义一个Cookie
	HttpCookie cookie = new HttpCookie("time"); 
	cookie.Value = DateTime.Now.ToLocalTime().ToString(); //注意设置过期时间,不然程序关闭就没有了 
	cookie.Expires = DateTime.Now.AddDays(1); 
	//将Cookie反馈到浏览器(赋值) 
	Response.SetCookie(cookie);
} 
//取值
protected void Button2_Click(object sender, EventArgs e) {
	if (Request.Cookies["time"] == null) 
	{
		Response.Write("没有您要读取的Cookie"); 
	}
	else {
	    Response.Write(Request.Cookies["time"].Value);
	}
} 
//清除Cookie
protected void Button3_Click(object sender, EventArgs e) {
	//千万不能用Request.Cookies.Remove(),因为这个方法,只是移除了副本,浏览器端的Cookie,服务端没有权利 移除!
	int num = Request.Cookies.Count; for (int i = 0; i < num; i++)
	{
		//自定义一个Cookie
		HttpCookie cookie = new HttpCookie("time"); 
		cookie.Value = DateTime.Now.ToLocalTime().ToString(); //注意设置过期时间,不然程序关闭就没有了 
		cookie.Expires = DateTime.Now.AddDays(1); 
		//将Cookie反馈到浏览器(赋值) 
		Response.SetCookie(cookie);
		HttpCookie hc = Request.Cookies[i];
		//服务端只有权利设置客户端Cookie过期时间,然后反馈给客户端,浏览器发现Cookie过期了,它就会去删
		hc.Expires = DateTime.Now.AddDays(-1); 
		//hc.Path="/虚拟目录名/文件夹名"; //如果设置了这个Path,只有在此文件夹下的页面才可以访问Cookie 
		Response.SetCookie(hc);
	} 
}

3.  Session提供了一种把信息保存在服务器内存中的方式,它能存储任何数据类型包括自定义的对象。保存和当前客户端相关联的数据。不要放太多的对象到Session,Session会有超时销毁的机制(服务器不知道浏览器是否关闭)。 

Session应用:验证码(防止暴力破解,暴力注册)。在ashx中调用Session,这个类一定要实现IRequiresSessionState接口。

Session是与Cookie相关联的,因为sessionid就保存在客户端的Cookie中,所以当用户关闭浏览器后,下次就访问不到(重新生成一个sessionid)指定的那一个Session了,而那块区域的Session会超时销毁。

掌握Session原理代码的意义。尝试写出来(赋值取值和直接调用ASP.NET提供的Session机制写出赋值取值),写出Session版本的数字自增
【session原理实现】
自定义session类 

public class SessionMgr {
	//static表示根据不同的sessionid可以创建多个不同的session,第一个string表示sessionId,第二个string表示用 户传递过来的name,object表示value值
	//下面的字典就是在服务端中存放的用户sessionId及其所对应的信息。
	private static IDictionary<string, IDictionary<string, object>> data = new Dictionary<string,
	IDictionary<string, object>>(); //下面的方法返回的数据就是Session,接受的参数就是由cookie传递过来的sessionId 
	public static IDictionary<string, object> GetSession(string sessionId)
	{
		if (data.ContainsKey(sessionId)) {
			return data[sessionId];
			//在内存中分配好一个Session区域,可以让用户存放数据。
	    }
		else
		{ 
			//用来判断拥有此sessionId的用户以前有没有记录,如果没有,就为他自动分配一个Session区域。
			IDictionary<string, object> session = new Dictionary<string,object>(); 
			data[sessionId] = session;
			return session;
		} 
	}
}

aspx.cs中的代码 

protected void Page_Load(object sender, EventArgs e) 
{
	//因为cookie是与当前用户使用的特定浏览器相关的,所以可以绑定sessionId //下面的if判断既是首次浏览,就自动为其分配一个sessionId
	if (Request.Cookies["MySessionId"] == null)
	{
		string sessionId = Guid.NewGuid().ToString();
		Response.SetCookie(new HttpCookie("MySessionId", sessionId)); 
	}
} 

//为指定用户设置其保留的内容
protected void Button1_Click(object sender, EventArgs e) 
{
	string sessionId = Request.Cookies["MySessionId"].Value; 
	IDictionary<string, object> session = SessionMgr.GetSession(sessionId); 
	session["服务端的数据"] = DateTime.Now.ToString(); 
	session["其他的数据"] = "Fuck you";
} 

//取出指定用户的保留信息
protected void Button2_Click(object sender, EventArgs e) 
{
	string sessionId = Request.Cookies["MySessionId"].Value;
	IDictionary<string, object> session = SessionMgr.GetSession(sessionId); 
	Button2.Text = Convert.ToString(session["服务端的数据"]) + session["其他的数据"];
}

进程内Session Session是保存在aspnet_wp.exe中的

Session丢失情况:
1、存放Session的电脑重启

2、InProc模式:aspnet_wp.exe或w3wp.exe在“任务管理器”中或其它情况下导致其进程被终止运行。

3、InProc模式:修改.cs文件后,编译了两次(只编译一次,有时不会丢失)

4、InProc模式:修改了Web.config

5、InProc模式,Windows 2003环境:应用程序池回收、停止后重启

6、InProc模式:服务器上bin目录里的.dll文件被更新

Session分三种:
1.InProc(进程内)-默认就是这种-速度快/但内存小/易丢失

进程外(有两种):可以在IIS或ASPNET服务意外关闭时继续保持状态,注意此时存储到session中的对象必须支持序列化:

2.StateServer:此时Session存储在aspnet_state.exe中

1.1修改配置文件<system.web><sessionState mode="StateServer"stateConnectionString="tcpip=localhost:42424"/>设置是否允许远程使用,直接收索--regedit(打开注册表)然后找到内容,将 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters的值改为1并且将localhost改为运行aspnet_state.exe那台电脑的ip

1.2默认端口号:424241.3开启服务:直接收索--services.msc(ASP.NET 状态服务)

3.SQLServer:此时Session存储在数据库中在vs的命令行中输入:

1.aspnet_regsql.exe -S 127.0.0.1 -U sa -P woshinibaba -ssadd -sstype c -d 数据库名
2. <sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="DataSource=.;Initial Catalog=test;uid=sa;pwd=woshinibaba"></sessionState>
3.对象必须可序列化 


二十、.aspx继承自 .aspx.cs, 他们之间的具体关系看反编译分析

1  .aspx.cs可以调用.aspx的runat="server"控件的原因?

编译之后,前台页面的runat="server"控件已经作为变量的方式到父类里面了

2  .aspx中可以访问后台aspx.cs的非私有成员的原因?

.aspx继承自.aspx.cs

3  浏览器请求页面的aspx时,服务器是通过反射创建了相应的页面对象来处理的。这个类是前台类还是后台类?是调用这个对象的什么方法来处理请求的?

前台类、 ProcessRequest()

4 服务器调用页面类对象返回html代码的过程?

先由页面类对象的 __buildControlTree()方法创建控件树,执行页面生命周期,然后调用页面对象的Render方法来循环遍历控件树,并分别调用每个控件相应的Render方法来产生每个控件相对应的html代码,最后组成整个页面的html代码。 


二十一、AJAX (Asynchronous JavaScript and XML, 异步JavaScript和XML)

是一种进行页面局部异步刷新的技术。用AJAX向服务器发送请求和获得服务器返回的数据并且更新到界面中,不是整个页面刷新而是在HTML页面中使用JavaScript创建XMLHTTPRequest对象来向服务器发出请求以及获得返回的数据,这样页面就不刷新了。XMLHTTPRequest是AJAX的核心对象。

原理性代码(重要): 

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript"> //杜绝中文!!!起名字的时候用英文(get提交的方式)
	function btnClick() { //分辨是不是IE浏览器,其他浏览器用标准的XMLHttpRequest,而IE用ActiveXObject var xmlhttp;
		if (window.XMLHttpRequest) {
			xmlhttp = new XMLHttpRequest(); 
		}
		else if (window.ActiveXObject) {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} 
		//true表示异步传输,false表示同步传输,后面加一个条件就是为了防止缓存 
		xmlhttp.open("get", "ShowTime.ashx?id="+new Date(), true); //注意字母的大小写
		xmlhttp.onreadystatechange = function () {
			//4表示接收数据完毕
			if (xmlhttp.readyState == 4) {
			//200表示服务端返回的报文正确 
				if (xmlhttp.status == 200) {
					document.getElementById("time").innerHTML = xmlhttp.responseText;}
			else {
				 alert("AJAX服务器返回错误!");
			} 
		}
	}; //向服务端发送请求 
	xmlhttp.send();
} 
</script>
</head>
<body>
<form id="form1" runat="server">
<div id="time"></div>
<input type="button" name="name" value="显示" οnclick="btnClick();"/> 
</form>
</body>
</html>

readyState属性指出了XMLHttpRequest对象在发送/接收数据过程中所处的几个状态。XMLHttpRequest对象会经历5种不同的状态。
0:对象已经创建,但未初始化。

1:已打开。对象已经创建并初始化,但还未调用send方法

2:已发送。已经调用send 方法,但该对象正在等待状态码和头的返回;

3:正在接收。已经接收了部分数据,但还不能使用该对象的属性和方法,因为状态和响应头不完整;

4:已加载。所有数据接收完毕 


二十二、JSONP (JSON with padding), 可以跨域加载数据,使用JSONP形式调用函数时, 如:"myurl?callback=?", query将自动替换?为正确的函数名,以执行回调函数。

为什么使用JSONP??如果不使用JSONP,当需要从别的网站获取信息的时候,页面加载,先去获取别的网站的信息,然而本网站的数据加载就要等待你获取完信息后才能加载,使用JSONP,实现了异步的操作,增强了客户体验。
例子: 

$(function(){ 
	//获取别的网站的JSON数据,放入(padding)到data中
	$.getJSON("http://9snow.org/weather/api?city=北京&callback=?",function(data){ //然后就可以在自己的网站利用别人网站的数据了
	}); 
});

二十三、控件的生命周期

1、由_builderControlTree()方法,完成页面控件树的创建

2、由LoadAllState()方法加载控件的状态管理信息,给控件保持状态(表单元素等除外)

3、ProcessPostData()对生成的控件树的控件进行一定的处理

4、Load事件,就是完成父类的Page_Load事件

5、ProcessPostData()对在Load事件中有可能动态生产的控件进行再加工

6、触发控件的事件

1) RaiseChangeEvents() 就是去执行**_**Changed一类的事件

2) RaisePostBackEvent() 就是去执行**_**Click一类的事件.......

Render

Unload

由上述控件的生命周期可以看出:"Load事件"是在"触发事件"执行之前执行的,因此,当你点击进行"触发事件"之后,肯定先要经过"Load事件"的处理,然后再处理"触发事件"的具体代码。 


二十四、 服务端控件简介

Label控件,AssociatedControlID属性用来关联一个控件

Literal控件也是展示一段文本,但是Literal控件不会渲染任何额外的标签,就是将Text属性的值展示出来而已。

onclick是服务端事件,onClientClick是最终生成到客户端浏览器中的onclick先执行渲染到客户端的onClientClick,再执行服务端的onclick

ClientID,控件在客户端的Id,控件在服务端的Id不一定等于客户端HTML中的Id,比如说在ListView等控件的模板中。在客户端使用方式:$('#<%=txt1.ClientID%>')

Visible属性,控件是否可见,如果Visible=False是不会渲染到HTML中的,这和在HTML中给元素style.display='none'效果是不一样的。

Attributes,用来设置获取控件的额外属性,或者在服务端注册事件,最终渲染后,还是执行的客户端js脚本。Button1.Attributes[“onmouseover”] = “alert(‘hello’)”; 


二十五、三种控件说明

1、HTML控件,ASP.Net把HTML控件当成普通字符串渲染到浏览器不去检查正确性,并且无法在服务端进行处理。

2、ASP.Net服务端控件,经过ASP.Net高度封装的控件,使用简单,运行在服务器端,可以在服务端使用C#代码进行操作,会渲染到客户端为HTML控件,【暴露的属性一般是C#的属性】

3、runat="server"的HTML控件。在HTML控件的基础上添加runat="server"也是运行在服务器端的,可以用C#代码进行操作,也会渲染到客户端。不像ASP.Net服务端控件那样高度封装,【暴露的属性大部分是普通HTML属性】。使用场合:如果控件没有被ASP.Net服务端控件封装的时候,用runat=server的HTML控件很方便。如td、div、label等 


二十六、显示图片的几种方式

1、HTML控件:<img src="images/bjxz.png" width="100" height="100"/>

2、runat="server"的HTML控件<img src="~/baodiao/images/bjxz.png" width="100" height="100"runat="server"/>

3、服务端控件<asp:Image ID="Image1" runat="server" ImageUrl="~/baodiao/images/bjxz.png"/>

4、ResolveClientUrl:<img src='<%=ResolveClientUrl("~/baodiao/images/bjxz.png")%>' width="100"height="100"/>

建议用第四种,避免了服务端控件,因为代码中如果有太多的runat=“server”会降低系统性能。 


二十七、关于数据绑定控件

关于数据绑定控件(具体代码参见“E:\传智终极版_李飞\练习总结\ASP.NET高级部分”)(注:所有的绑定操作都是在Page_Load事件之后进行的,因为,拖拽的绑定控件是最终Render到aspx页面的)

I) DropDownList

DropDownList显示来自于ObjectDataSource的数据,选择数据源(DataSourceID属性)为刚才的ObjectDataSource,

并且设定显示字段(DataTextField)和值字段(DataValueField)即可

II) Repeater

Repeater(foreach)用于对绑定数据源中的数据进行遍历并按格式显示(自己本身并不输出),每条数据以什么格式显示是由Repeater的<ItemTemplate>来决定的

<%=控件ID.ClientID%>,<%#Eval("UserName")%>,<%#Bind("UserName")%>的区别?

<%=控件ID.ClientID%>是指在进行js操作时,从服务端控件中得到Id,如果直接写Id,有可能有客户端生成的Id不一致,所以要用ClientID。<%#Eval("UserName")%>是指从数据库中取得字段为UserName的值并显示在页面上(只读)

Eval的其他的用法:
1、<%# Eval("字符串"),"{0:c}" %> 以钱币的形式显示
2、<%# Eval("时间字符串"),"{0:yyyy-MM-dd}" %> 以特定格式的日期形式显示

<%#Bind("UserName")%>是双向绑定,不但可以进行读操作,也可以将修改的数据更新到数据库中。

//Eval()在处理字符时,如果字符格式如:01.jpg,它解析之后的结果为1.jpg,所以要进行处理,在父类中自定义一个方法进行处理(因为Eval返回值类型为object,所以参数也是object类型): 

protected string GetFullPath(object url) 
{
	string urlPath = url.ToString();
	int intName = Convert.ToInt32(Path.GetFileNameWithoutExtension(urlPath)); 
	if (intName < 10)
	{
		urlPath = "0" + urlPath; 
	}
	return urlPath; 
}

然后在页面中如下调用即可以了
<img src='../images/<%#GetFullPath(Eval("Url")) %>' />

Repeater的两个事件:ItemDataBound、ItemCommand

ItemDataBound是在控件绑定完成之后触发,依次对每一行进行判断。ItemCommand是在绑定完成之后,对其项进行处理(一般是按钮的事件)。

Repeater可以使用这个 <%# Container.ItemIndex+1%> 方式进行编号 

III) ListView

ObjectDataSource(ListView) 高效分页操作步骤:
1、查询共多少条数据GetCount() 返回int
2、查询第几页的数据GetPaged(int startRowIndex,int maximumRows) 返回泛型集合

pageIndex 当前页码-1
pageSize 每页几条数据
select * from (select *,row_number() over(order by pid desc) as num from photos) as t where num > @startRowIndex and num<= @startRowIndex+@maximumRows order by pid desc作为ObjectDataSource的数据源

3、选择ObjectDataSource的SelectMethod属性 =GetPagedEnablePaging = true
SelectCountMethod = GetCount

4、在页面上,把ObjectDataSource生成的参数删除<asp:Parameter Name="startRowIndex" Type="Int32" /><asp:Parameter Name="maximumRows" Type="Int32" />

5、可以设置DataPager的控件PageSize属性(决定每页几条数据)可以设置QueryStringField的值为pageNumber,就可以get方式提交,看出第几页了 


二十八、 母版页

如果一个子页面想操作母版页中的内容(如点击子页面中的名字为Button1的按钮,将母版页中的Id为ButtonMaster按钮的文本显示出来),可以用以下方法:

protected void Button1_Click(object sender, EventArgs e)
{
	Button btn = Master.FindControl("ButtonMaster") as Button; 
	Response.Write(btn.Text);
}


二十九、 缓存

什么时候用缓存?

1. 页面上的数据不经常变化;

2. 访问量比较大缓存是一种用空间换时间的技术,存在于计算机中很多的地方,用来将一些慢速设备中的常用数据保存在快速设备中,存取数据的时候直接从快速设备中取。

缓存存在失效的问题:为了保证从缓存中读取数据和慢速数据中数据一致,则需要在慢速数据中对应的数据发生变化的时候,清除缓存中相应的数据。

缓存是改进网站性能的第一手段,就像索引是改进数据库性能的第一手段一样。ASP.NET缓存主要分为:页面缓存、数据源缓存、缓存依赖这三种主要类型(都是缓存在服务端的!)。

缓存实现大致原理代码:

protected void Page_Load(object sender, EventArgs e)
{
	List<Model.T_Photo> list = new List<Model.T_Photo>(); 
	if (Cache["photo"] == null)
	{
		BLL.T_PhotoBLL bll = new BLL.T_PhotoBLL();
		list = bll.GetAll(); //首次加载,从数据库获得数据,并将数据保存在缓存中,以后取数据,就直接从缓存中取了!
		Cache["photo"] = list; 
		//如果写成下面的形式,大致就是自定义缓存的原理(设置了滑动过期时间): 
		//Cache.Insert("photo",list,null,Cache.NoAbsoluteExpiration,new TimeSpan(0,10,0));
	} else {
		list = Cache["photo"] as List<Model.T_Photo>; 
	}
	foreach (Model.T_Photo photo in list) {
		Response.Write(photo.Title+"<br />"); 
	}
}

1、页面缓存
使用方法:在页面头加如下代码:

<%@ OutputCache Duration="10" VaryByParam="none" %>可以指定根据哪项进行缓存,如:点击进入新闻详细页面,而每条新闻的newsId是不一样的,所以可以根据newsId进行缓存,VaryByParam="newsId"(写在新闻展示页面),如果有多项,之间有;分割。如果想让任何不同的查询字符串都创建不同的缓存,则设置VaryByParam="*",一般情况下设置“*”就足够。

页面的局部缓存(最好不要这样使用,用AJAX更好)大致思路,先设置页面缓存,然后在不需要进行缓存的地方使用<asp:Substitution ID="Substitution1"MethodName="NoCache" runat="server" />,然后在后台写对应的实现的方法,如:

//这里对应的内容可以不缓存!
public static string NoCache(HttpContext hc){

return DateTime.Now.ToString();}

2、数据源缓存设定ObjectDataSource的CacheDuration(缓存时间:秒),EnableCaching=true。即可。

3、缓存依赖(滑动策略)1) 依赖于文件

//文件的物理全路径
string path=Request.MapPath("fileName");

CacheDependency dep=new CacheDependency(path);//参数:缓存名,缓存内容,依赖的文件(当文件个数或内容发生变化时,才重新缓存,否则保持原来的缓存内容)

Cache.Insert("photo", list, dep);

2) 依赖于数据库
I) 轮询机制:FW主动到数据库检查数据是否改变
1、数据库缓存依赖
-S服务器名称 -E集成身份验证 -ed启动 -d数据库名称 -et指定缓冲依赖的表名 -t表名在vs2010的命令提示符中运行(切换到aspnet_regsql.exe(先启用它)所在的目录)aspnet_regsql -S . -E -ed -d PhotoShow -et -t Comments

缓存依赖禁用该数据库
aspnet_regsql -S . -E -dd -d PhotoShow

2、依赖于数据库的web.config配置 

<system.web>
	<caching>
		<sqlCacheDependency enabled="true">
			<databases>
				<add name="PhotoShow" connectionStringName="连接字符串所对应的名字" pollTime="500"/>
			</databases> 
		</sqlCacheDependency>
	</caching>
</system.web>

II) 通知机制:数据库通知FW数据是否改变 


三十、错误页

配置错误页,只要在Web.config中的<system.web></system.web>中添加以下代码 :

<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/ErrorPage/ExceptionError.htm"> 
	//处理异常信息
	<error statusCode="403" redirect="NoAccess.htm" />
	<error statusCode="404" redirect="~/ErrorPage/NotFound.htm" />
</customErrors>

mode有三个可选项On(总是显示定制错误页),Off(直接显示调用堆栈等异常信息),RemoteOnly(对于本机访问显示调用堆栈等异常信息,对于外部用户显示错误页面)一般选择RemoteOnly 


三十一、 IHttpModule就是起一个页面加载前的过滤作用 (下例就是进行了身份验证)

/// 注意:要实现IHttpModule这个接口的类,才可以进行处理 
public class TestRight:IHttpModule
{
   public TestRight()
   {
   }
   public void Dispose() 
   {
   }
    
   public void Init(HttpApplication context) 
   {
		//对于处理Session的问题,不能使用context.BeginRequest注册事件,因为BeginRequest处理这个事件之前,还 没有创建Session呢,AcquireRequestState事件是在Session创建之后才触发的
		context.AcquireRequestState += new EventHandler(context_AcquireRequestState); 
	}

	void context_AcquireRequestState(object sender, EventArgs e) 
	{
		//在这里进行权限验证,只要这里写一次,所有的页面加载的时候都会验证有没有登陆,没有登陆的话,转向登陆 页面,让其先进行登陆工作。其实有的时候,也可以将这里的代码写在全局文件中,不过那样做的话,全局文件中的代码 会很多,所以交给HttpModule来完成!
		HttpApplication app = sender as HttpApplication; //在进行处理之前,应该将一些内容屏蔽掉,如登陆页面、图片、js、css等 //如下面不屏蔽掉Login页面,永远就没有登陆的机会了,也就死循环了!!!即不是登陆页面的话,就进行权限
的判断
		if (!app.Request.RawUrl.ToLower().Contains("login.aspx") && !
		app.Request.RawUrl.ToLower().Contains("/images"))
		{
		//判断有没有登陆(注意:在请求照片的时候,根本就没有Session这一说法,所以在上面if判断要把照片也
		排除掉)
			if (app.Session["isLogin"] != "true")
			{
				//加url的原因:转向登陆页面后,如果登陆成功,直接转向你登陆之前想要进入的那个页面
				app.Response.Write("<script>alert('请先登录');window.location.href='Login.aspx? returnUrl="+app.Request.RawUrl+"'</script>");
			} 
		}
	} 
}

在Login.aspx.cs中的大致代码:

string url = Request.QueryString["returnUrl"];
//直接进入登陆页面登陆的,转向default页面 if (string.IsNullOrEmpty(url))
{
    Response.Redirect("Default.aspx");
}
//通过别的页面重定向到登陆页面登陆的,登陆成功之后,转向之前你想查看的页面 
else
{
	Response.Redirect(url); 
}

在配置文件中,对实现IHttpModule的类进行配置 

<system.web>
	<compilation debug="true" targetFramework="4.0"/>
	<httpModules>
		<add name="test" type="TestRight"/>
     </httpModules>
</system.web>

三十二、url重写

UrlRewrite (伪静态) ,一般处理动态页面

1、有利于SEO,带参数的Url权重较低;2、地址看起来更正规

用IIS做服务器的时候,静态页面、图片、js等不会触发Application_BeginRequest事件在请求动态页面的时候,哪怕请求文件不存在,也会经过Application_BeginRequest事件 

//Url重写大致代码:
protected void Application_BeginRequest(object sender, EventArgs e) 
{
	//得到请求文件的虚拟路径 如 ~/AddComment-67.aspx
	string virtualPath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath; 
	//如果用户请求的是http://localhost:1050/AddComment-67.aspx这样的页面 //实际在后台处理的是http://localhost:1050/AddComment.aspx?id=67 //但显示给用户的url地址就是请求的页面地址
	Match match = Regex.Match(virtualPath, @"~/AddComment-(\d+)\.aspx");
	if (match.Success)
	{
		string id=match.Groups[1].Value;
	    HttpContext.Current.RewritePath("~/AddComment.aspx?id="+id);
	}
}

可以使用插件完成此功能:“URLRewriter.dll”步骤:
添加对URLRewriter.dll的引用

1、在<configSections>节点加入 

<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />

2、在</configSections>之后加入 

<RewriterConfig> <Rules>
          <RewriterRule>
            <LookFor>~/(\d{4})/(\d{2})/Default\.htm</LookFor>
            <SendTo>~/Default.aspx?ID=$1</SendTo>
          </RewriterRule>
        </Rules>
</RewriterConfig>

3、<httpHandlers>中加入

<add verb="*" path="*.htm" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />


三十三、 关于网站的发布

1、VS中设置为Release,将网站发布出来

2、在IIS部署网站(发布或者拷贝都可以)。在配置文件中将<compilation debug="true" targetFramework="4.0"/>debug设置为false,删掉cs代码

3、上传文件夹不给执行权限:在iis管理器中找到上传文件夹,选择属性--执行权限,设置为“无”。这样哪怕利用漏洞上传了可执行代码到上传文件夹,也无法执行。

4、取消所有文件夹的浏览权限,防止用户查看网站的文件列表,在iis管理器中找到主站节点→属性→主目录→取消“目录浏览”。

5、IIS管理中,Web服务器扩展,只允许asp.net那几个,其他的CGI、ASP等全部禁止。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋恨雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值