浅谈ASP.NET的内部机制(一)
前言 当一个Http请求发送给一个aspx页面时 服务器进行了哪些操作?又如何来解析这个请求?ASP NET在接收请求后是怎么运行的 如怎么编译以及怎么样用托管的代码来运行的?……理解这些问题 使我们可以更加好的开发ASP NET 当我们在浏览器中请求一个ASP NET网站的某个页面的时候 如 我们在浏览器中输入 x 这个请求就被发送到了服务器(当然了 这个网站是部署在IIS中的) 当请求到达了服务器之后 那么IIS就开始进行一系列的操作 注意 不是每个请求都一定会由ASP NET来运行处理的 大家稍后就会明白为什么 在IIS中有一个组件 sys 其实这个组件的作用很简单 就是验证请求的url 如之前的 x 如果请求的URL不符合 sys的要求 那么这个请求就不会被传递给ASP NET的处理程序 这样就在IIS这道门槛这些阻止了不合法的url请求 这样ASP NET就不用处理这个不合法的请求 就减轻了服务器的压力 下面 我们就来看看这个 sys到底是怎么样处理请求的url的 当大家明白这个问题后 就可以帮助我们解决很多的以前遇到的问题 首先请大家看看下面的图 当发送一个请求来请求页面的时候 sys就会检查这个请求的url和headers的总的大小 包含检查url中有关查询字符串的大小 如demo aspx?username=demo 也会检查cookie的大小 把这些所有的加起来 看看它们是否超过了 KB 如果超过了 请求就失败了 所以请求根本就没有传递给ASP NET 而且在 sys检查url的时候也有很多的要求的 如我们之前的那个url x 这个url是由localhost Demo aspx 这些路径的片段组成的 每一个由 / 分割的字符串都是一个路径片段 本例中就有两个路径片段 在默认情况下 sys要求一个url的路径片段不超过 个 并且每个路径片段的大小也不要超过 个字母 但是注意 如果在Demo aspx后面有查询字符串 Demo aspx?page= 那么这个片段就可以超过 个字母的限制 即 Demo aspx?page= 可以更大 但是不管怎么样 这些url的大小 如之前所说的 不能超过 KB 如果没有通过 sys的要求 IIS就发送一个 的错误 之前也说了的 那是默认的这只 其实这些设置我们是可以在注册表中改的 但是默认设置已经很不错了 所以一般没有必要改 当请求的url通过了 sys的检查后 请求就会传递给aspnet_filter dll 下面简称filter 其实这个filter做两件事 将url中的无cookie的票据转换为Http Headers 保护ASP NET的相应的目录 首先来看看第一个作用 检查url中的无cookie信息 并且转换为Http Headers 大家应该明白ASP NET 中的新特性-支持无cookie 即cookieless 因为我们在进行验证的时候一般是基于Forms验证 而这种验证方式是把信息保存在cookie中的 但是有的用户的浏览器是禁用了cookie的 所以为了使得我们可以继续用这个验证方式 就把验证信息保存为无cookie 大家可以去查看有关这方面的资料 来看看下面的一个url //localhost/demo/(S(tuucni xfzj xqx mnqdg ))/Default aspx 我们其实把有关的信息存储在了url中 如上面的 S 就标识在后面括号 () 的信息就是无cookie的信息(tuucni xfzj xqx mnqdg ) 来看看 S 是什么 S—Cookieless ticket for session state A—Cookieless ticket for anonymous identification F—Cookieless ticket for forms authentication 其实filter并不知道这些标识(如 S )的意义 只是filter检查url中是否包含这些标识 并且这些标识后面还有 () 如果在url中检查到有这些标识 那么filter就把这些标识转换为Http Headers 并且在url中删除这些标识 我们本来请求的是x页面 但是如果filter不删除标识 那么我们请求//localhost/demo/(S(tuucni xfzj xqx mnqdg ))/Default aspx是不存在的 就会返回一个 错误(找不到请求的文件) 现在我们来看看filter的第二个作用的 保护ASP NET的相应的目录 在我们开发的ASP MET网站中 有很多的文件目录是不允许访问的 如我们存放数据的App_Data App_Code等 所以filter就会检查请求的url中是否包含这样的字符 //localhost/demo/App_Code/…一旦发现有这样的字符串出现 甚至是以 App_ 开发的任何字符串 如 App_MyFolder 这个请求就会被拒绝了 但是 假如你的项目中已经有一个这样的以 App_ 命名的目录 如果你非要可以访问这样的目录 可以在注册表中修改设置HKEY_LOCAL_MACHINE\Sofare\Microsoft\ASP NET lishixinzhi/Article/program/net/201311/12257
浅谈ASP.NET内部机制(三)
大家已经在知道 在我们开发ASP NET网站的时候 每个服务器控件都有自己的ID 为了后面更好的展开 下面我们就来简单的看看这个场景 当我们在浏览器中点击了一个服务器控件 如 Button 此时页面回传给服务器 然后服务器就引发控件的Click等事件 这个场景是简单的不能在简单了 我们来进一步看 我们知道 不是所有的控件都会在服务器端触发事件的 比如 submit按钮 这个按钮也同样可以把表单数据传到服务器 但是这个控件不能在服务器端触发事件 其实在一个页面提交到了服务器之后 服务器就会检查是哪个控件引起了页面提交 然后就把这个控件的ID找到 然后再在我们请求的那个页面 如Default aspx (假设我们点击按钮 请求的是Default aspx) 去找是否有服务器控件的ID和此时提交页面的ID是一样的 如果有 那么就在页面的生命周期的合适的时候 引发事件 在把处理的结果返回 如果没有 服务器就不做什么了特别的处理 还有一点要注意的是 在查找那个控件的ID 的时候 页面(如Default aspx) 已经被编译成为了一个继承自Page的类 当然 上面说的只是一个很粗略额过程 希望大家有个总体的认识 下面就细致的讲解 我通过一个流程来解释 我们首先请求一个服务器端的页面 如 x 为了方便解释 假设页面只有三个服务器控件 TextBox DropDowmList Button 定义如下 Untitled Page 在浏览器中 我们在 源 中 看到的如下 <!DOCTYPE PUBLIC //W C//DTD XHTML Transitional//EN transitional dtd > Untitled Page <input type= hidden name= __VIEWSTATE id= __VIEWSTATE value= /wEPDwUKMTAxNzk MjY OWRkxj+ HeO c N xVutp x OdaSpw= /> Text Text Text 确实 上面的那些HTML的代码确实没有什么 但是大家注意看看TextBox DropDownList 它们的ID在服务器端的aspx页面和本地的源中的ID是一样的 我们在浏览器中的TextBox中输入 xiaoyang 然后DropDowList 选中 Text 然后我们点击按钮 提交 此时我们提交的数据被包含在表单中的 而且是以这样的格式保存的 TextBox =xiaoyang&DropDownList =Value 不用多说 表单数据是用 & 来分隔的 而且每个分隔的串包含两个部分 ID和值 也就是 键值对 数据到了服务器后 ASP NET就实例化一个 HttpRequest的类 这个类有两个属性 Forms和 QueryString 它们的类型都是NameValueCollection(键值对 大家可以把它看成一个HashTable) 然后ASP NET解析表单数据 表单数据就解析成为了一个个的键值对 然后就保存在Forms(POST提交)或者QueryString中(GET提交) 我们之前是以POST提交为例子的 之前的事情是发生在页面的生命周期之前的 当页面调用自己的ProcessRequest方法后 就进入了页面生命周期 此时页面就会检查页面中的所有控件 看看它们有哪些实现了IPostBackDataHandler接口 然后把实现了这些接口的控件都放入到一个ArrayList中 然后也检查哪些控件实现了IPostBackEventHandler 也把它们假如到另外的集合中 之后就开发遍历实现了IPostBackDataHandler控件的集合 并且调用IPostBackDataHandler的方法 LoadPostData(string postdatakey NameValueCollection value) 之前说过了的 我们提交的表单的值都保存在了Forms中(它的类型是NameValueCollection 的) 所以此时这些值就传入到了这个方法 然后就检查这些值和之前的是不是相同的 我们已经还记得 我们在浏览器中看到页面时 页面中的TextBox 初始时是没有值的 而且DropDownList选择的是Text 现在我们的值改了 是 xiaoyang 和 Text 所以这个方法检查的结果是 值变了 返回了true 只要返回了true 那么IPostBackDataHandler的下一个方法就会调用RaisePostDataChangeEvent() 这个方法已经注册了事件 到页面生命周期的之后就后引发的 所以 如果我们开发的自定义控件想要在数据改变的时候引发事件 那么就一定要实现IPostBackDataHandler接口 例子可以参看我的另外的控件开发的系列文章 现在我们已经说到了数据的改变 下面就看看到底是怎么引发事件的 到了页面开发执行RaisePostbackEvent方法的时候 页面就会遍历实现了IPostBackEventHandler的控件的集合 并且检查是否在页面中存在一个控件 这个控件要实现了IPostBackEventHandler 并且ID和之前使得页面提交到服务器的的那个控件的ID一样 如果有IPostBackEventHandler的RaisePostBackEvent 方法来触发事件(不同控件实现这个方法的方式不同) 如Click事件 所以 如果想在自定义控件可以触发事件 那么就要实现IPostBackEventHandler接口 可以参看我的控件开发系列文章 有例子的 lishixinzhi/Article/program/net/201311/12865
求一个简单的ASP留言板代码
再也不能简单的留言系统啦!
数据库字段为:
id name message 三个字段。
下面是一个文本域,可以再里面留言。
文件名是:001.html
网络大名:
将文本域提交的内容写进数据库。
文件名为:001.asp
set conn=server.createobject("adodb.connection")
conn.open "driver={microsoft access driver (*.mdb)};dbq="&server.mappath("003.mdb")
name=request.form("name")
message=request.form("message")
exec="insert into guestbook(name,message)values('"+name+"','"+message+"')"
conn.execute exec
conn.close
set conn=nothing
response.write "记录添加成功!"
%>
asp,设计一个简单的留言板,在线等
'这是添加留言的页面add.asp
'我没看见你的数据库表的名字,于是就用的lyb,你可以改,95%手打,望采纳
新增留言
<%
if request("action") = "add" then
call add()
end if
%>
主题
内容
姓名
邮箱
<%
sub add()
zt=request("zt")
nr=request("nr")
xm=request("nr")
yx=request("yx")
set rs = server.CreateObject ("adodb.recordset")
sql="select * from lyb"
rs.open sql,conn,1,3
if rs.eof and rs.bof then
rs.AddNew
rs("title")=zt
rs("body")=nr
rs("name")=xm
rs("yx")=email
rs("submit_date")=now()
rs.update
response.write("添加成功!")
else
reponse.write("添加失败!")
end if
rs.close
set rs=nothing
end sub
%>
'这是留言查看页面带删除功能 index.asp
留言板
<%
if request("action") = "del" then
call del()
end if
%>
主题
内容
姓名
邮箱
删除
<%
set rs = server.CreateObject ("adodb.recordset")
sql="select *from lyb order by submit_date desc" '这里的表名为数据库表名,排序为时间降序
rs.open sql conn 3,1
do while rs.eof=false
%>
" onClick="JavaScript:return confirm('确认删除吗?!')">删除
<%
rs.movenext
loop
%>
<%
sub del()
id=request("id")
set rs=conn.execute("delete from lyb where id="&id)
response.write("删除成功!")
end sub
%>
'这是数据库连接文件 conn.asp
<%
set connection=Server.CreateObject("ADODB.Connection")
DBPath = Server.MapPath("Guest.mdb")
connection.Open "provider=microsoft.jet.oledb.4.0;data source="&dbpath
%>
求asp无限级树型菜单源代码,最好是带数据库的!
关于SELECT的无限联动菜单
index.asp
程序代码:
<!--
FONT{font-size:12px}
TD{font-size:12px}
A{color:#333399}
A:hover{color:#FF6600}
-->
<!--
function funOnload(){
document.all.list_file.src="jscript_city.asp?base=0&sele=0-&elem=Select01";
}
//pBase级数,以0基,
//pSele是<option 的value值
//pEle是下一级的表单名字
function chgSelect(pBase,pSele,pElem){
//当改变了一个列表之后。清除以后的列表的值。
for(i=parseInt(pElem.replace("Select",""));i<=5;i++){
var tmp="000"+i;
var pElem1=eval("document.Form1.Select"+tmp.substr(tmp.length-2));
pElem1.length=1;
pElem1.selectedIndex=0;
}
//JS用ASP得到数据库的数据来更新下级列表
document.all.list_file.src="jscript_city.asp?base="+pBase+"&sele="+pSele+"&elem="+pElem;
}
//-->
省...
市...
县...
乡...
村...
'jscript_city.asp
程序代码:
<%
' varBase 下拉菜单等级
' varSele 所选择下拉菜单项的数据库ID
' varElem 下一级的表单名称
varBase=Request.QueryString("base")
varSele=Left(Request.QueryString("sele"),InStr(Request.QueryString("sele"),"-")-1)
varElem=Request.QueryString("elem")
varDistName=""
varAutoID=""
Set conDB=Server.CreateObject("ADODB.CONNECTION")
conDB.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ="&Server.Mappath("db1.mdb")
sqlCommand="select * from table1 where filed1="&varBase&" and filed2="&varSele
Set rsRecord=conDB.Execute(sqlCommand)
While Not rsRecord.eof
varDistName=varDistName&chr(34)&rsRecord("filed3")&chr(34)
varAutoID=varAutoID&chr(34)&rsRecord("id")&chr(34)
rsRecord.movenext
If Not rsRecord.Eof Then
varDistName=varDistName&","
varAutoID=varAutoID&","
End If
Wend
Response.Write("var varDistName=new Array("&varDistName&")"&vbcrlf)
Response.Write("var varAutoID=new Array("&varAutoID&")"&vbcrlf)
Response.Write("var varElem=eval("&chr(34)&"document.Form1."&varElem&chr(34)&")"&vbcrlf)
Response.Write("varElem.length=varDistName.length+1;"&vbcrlf)
Response.Write("for(var i=0;i<varDistName.length;i++){"&vbcrlf)
Response.Write(" varElem.options[i+1].text=varDistName;"&vbcrlf)
Response.Write(" varElem.options[i+1].value=varAutoID+'-'+varDistName;"&vbcrlf)
Response.Write("}"&vbcrlf)
Response.Write("varElem.selectedIndex=0;"&vbcrlf)
%>
db1.mdb
'-------------------------------------------------
福建 厦门 思明 黄厝 曾厝桉村
福建 泉州 丰泽 西湖 水头村
如上面的五级转成数据库为:
'-------------------------------
id filed1 filed2 filed3
1 0 0 福建
2 1 1 厦门
3 1 1 泉州
4 2 2 思明
5 3 4 黄厝
6 4 5 曾厝桉村
7 2 3 丰泽
8 3 7 西湖
9 4 8 水头村
'-------------------------------------------------
数据库说明:
id 自动编号
filed1 下拉菜单列表的等级(看级数。可以设置它的精度。是数字类型)
filed2 上一级的id号(用长整型吧)
filed3 这个就不用说了吧(文件。长度自己看情况)
本程序在IIS4+WIN2000P+ACCESS2000下通过。
求一个dreamweaver制作的个人主页的源代码,要求是连接数据库的动态网页。
要用到ASP动态网页设计啊!
首先我们先做准备工作,先做一下策划,看看我们可能要做哪些页面,所谓说好的开始就是成功的一半,所以大家不要急着做,听我慢慢讲来。为了让大家都能制作出自己的留言板,尽量实现一个网页一个功能模块,我们就做以下六个网页:
一、index.asp----首页即显示留言页
二、conn.asp----公共网页,每个网页都要包含它,是连接打开数据库的操作。
三、write.asp和save.asp----分别是发表留言的表单网页和保存留言页。
四、del.asp----删除留言页
五、reply.asp----回复当前留言页
做好的留言板效果图如下:
好了,说到这里我们可以动工了,首先做一个最重要的工作,就是建立起一个数据库,将来存放网友的留言所用。
1、数据库名:db1.mdb
2、数据库表:只有一个表:book
3、数据表book里增设以下字段,见图1
说明:?任一字段的数据类型中的“常归”项中的“允许空字符串”最好填“是”
?日期/时间的“常归”项中默认值为Now();站长回复里的“常归”项中的默认值为“暂没有回复”,注意此处要加双引号,是半角而不是全角。
数据库建好后开始做公共网页,用来打开数据库,打开Dreamweaver MX,按如下方法新建动态ASP网页:
并保存为CONN.ASP,在编辑区里切换到显示代码视图里,注意把第一行自动生成的代码删掉。
这次主要是写连接数据库和参数设置的ASP代码,不用输出什么HTML标签,所以把代码全部删掉,用DREAWMEAVER插入栏自带的ASP对象写入以下代码,ASP栏里没有的代码只能自己手写输入了。
注意要把所有要编译的ASP代码放在之间,这样才能正常运行,否则会出错!这是基本常识哦。让我解释以上代码的意思吧:
代码第一行: 用来建立connection对象,connection对象扮演着十分重要的前期连接工作,连接成功数据库才会有以后的数据操作功能。
代码第二行:设置数据库连接参数。包括有数据库驱动程序和数据库文件名。
代码第三行:用conn连接对象打开数据库。
这些是通用连接数据库的方法,任何需要打开数据库的动态网页都可以照搬以上代码就行了,只把数据库的名字换成你的数据库名字就行了,注意路径要正确。所以可以把这些代码用Dreawmeaver里的代码片断复制下来,以后直接插入就可以用了,比较方便,也不用记忆,这是一个小技艺吧!
求做一个电影信息资料库ASP源代码,可以实现删除,录入,更新的功能,
string str1 = "insert into user1 values('" + this.TextBox1.Text.Trim() + "','" + this.TextBox11.Text.Trim() + "','" + this.TextBox2.Text.Trim() + "','" + this.DropDownList1.SelectedValue + "','" + this.RadioButtonList1.SelectedItem.Text + "','" + this.TextBox10.Text.Trim() + "','" + this.TextBox9.Text.Trim() + "','" + filename1 + "')";
SqlCommand cmd1 = new SqlCommand(str1, con1);