ASP网页编程之在ASP与ASP.NET之间同享对话形态
无法实现跨操作系统的应用。当然这也是微软的理由之一,只有这样才能发挥ASP最佳的能力。可是我却认为正是Windows限制了ASP,ASP的概念本就是为一个能让系统运行于一个大的多样化环境而设计的;asp.net[媒介:]ASP.NET是微软供应的最新的开辟基于Web的使用法式的手艺。它供应了大批的比传统ASP剧本手艺的优点,包含:
1)经由过程把UI体现层(presentation)与贸易逻辑(business logic)分隔创立了更好的开辟布局;
2)利用完整编译的代码取代了传统ASP的代码翻译;
3)它编译特征与每一个撑持的办法协同,这意味着利用ASP.NET的站点比利用传统的ASP站点的功能更高。
虽然把存在的ASP使用法式转换到ASP.NET有良多潜伏的优点,也有些ASP使用法式义务很主要而且庞杂。转换进程能够需求更多资本并给使用法式带来更多风险。处理这些成绩的路子之一是同时运转ASP和ASP.NET使用法式,在一个时辰将一个对话转换为ASP.NET。为了同时运转新旧法式,需求创立一个机制在传统的ASP与ASP.NET间同享对话形态。本文会商的是如何利用.NET框架组件的类和序列化特征同享形态信息。
概述
Cookie是Web使用法式辨认用户对话的最经常使用的办法,可以用于辨认传统的ASP和ASP.NET对话形态。在ASP剧本中形态信息保留在内存中,不克不及与其它使用法式(例如ASP.NET)同享。假如对话形态利用通用格局保留在微软SQL Server中,它就能够被传统的ASP和ASP.NET配合会见。
在本例中,名为mySession的Cookie用于辨认用户对话。当用户对Web使用法式作出恳求时,将为该用户发生独一的Cookie用于辨认对话。在随后的恳求中,阅读器将该独一的Cookie发送回办事器用来辨认对话。在被恳求的Web页载入前,一个自界说对象将利用该独一的Cookie从SQL Server中从头载入用户对话数据。经由过程自界说对象Web页中的对话形态是可以会见的。Web恳求完成后,假如恳求终止,对话数据将保留回SQL Server(见图1)。
图1.数据流复杂图
ASP.NET完成
在ASP.NET中每个Web页都衍生自System.Web.UI.Page类。Page类纠合了HttpSession对象的一个实例用于处置对话数据。在本例中,叫做SessionPage的自界说Page类来衍生自System.Web.UI.Page,供应了相似Page类的一切特征。独一的区分是默许的HttpSession利用自界说的对话对象重载了(对实例变量利用new修正符,C#答应衍生的类埋没基类的成员)。
public class SessionPage : System.Web.UI.Page
{
...
public new mySession Session = null;
...
}
自界说的对话类利用HybridDictionary对象来响应保留内存中的对话形态(HybridDictionary可用于处置恣意数目的对话元素)。为了与传统的ASP通用,该自界说对话对象将限制对话数据类型为字符串型(默许的HttpSession答应对话保留恣意类型的数据,不克不及与传统的ASP通用)。
public class mySession
{
private HybridDictionary dic = new HybridDictionary();
public mySession()
{
}
public string this
{
get
{
return (string)dic;
}
set
{
dic = value;
}
}
}
Page类为定制表露了分歧的事务和办法。出格是OnInit办法用于设置Page对象的初始化形态。假如恳求不包括名为mySession的Cookie,将为恳求者发生一个新的mySession Cookie。别的,对话数据将利用自界说数据会见对象SessionPersistence从SQL Server中检索出来。DSN和SessionExpiration的值从web.config中检索。
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
cookie = this.Request.Cookies;
if (cookie == null)
{
Session = new mySession();
CreateNewSessionCookie();
IsNewSession = true;
}
else
Session = sessionPersistence.LoadSession(
Server.UrlDecode(cookie.Value).ToLower().Trim(),
dsn,
SessionExpiration
);
this.Unload += new EventHandler(this.PersistSession);
}
private void CreateNewSessionCookie()
{
cookie = new HttpCookie(sessionPersistence.SessionID,
sessionPersistence.GenerateKey());
this.Response.Cookies.Add(cookie);
}
SessionPersistence类利用微软.NET框架组件的BinaryFormatter来串行化和并行化对话形态为二进制格局以供应最好功能。了局的二进制对话数据接着作为图像字段类型被存入SQL Server。
public mySession LoadSession(string key, string dsn,
int SessionExpiration)
{
SqlConnection conn = new SqlConnection(dsn);
SqlCommand LoadCmd = new SqlCommand();
LoadCmd.CommandText = command;
LoadCmd.Connection = conn;
SqlDataReader reader = null;
mySession Session = null;
try
{
LoadCmd.Parameters.Add("@ID", new Guid(key));
conn.Open();
reader = LoadCmd.ExecuteReader();
if (reader.Read())
{
DateTime LastAccessed =reader.GetDateTime(1).AddMinutes(SessionExpiration);
if (LastAccessed >= DateTime.Now)
Session = Deserialize((Byte[])reader["Data"]);
}
}
finally
{
if (reader != null)
reader.Close();
if (conn != null)
conn.Close();
}
return Session;
}
private mySession Deserialize(Byte[] state)
{
if (state == null) return null;
mySession Session = null;
Stream stream = null;
try
{
stream = new MemoryStream();
stream.Write(state, 0, state.Length);
stream.Position = 0;
IFormatter formatter = new BinaryFormatter();
Session = (mySession)formatter.Deserialize(stream);
}
finally
{
if (stream != null)
stream.Close();
}
return Session;
}
在恳求的末尾,Page类的Unload事务被启动了,一个同Unload事务一同注册的事务处置办法将串行化对话数据为二进制格局并将了局二进制数据存入SQL Server。
private void PersistSession(Object obj, System.EventArgs arg)
{ sessionPersistence.SaveSession(
Server.UrlDecode(cookie.Value).ToLower().Trim(), dsn, Session, IsNewSession);
}
public void SaveSession(string key, string dsn,
mySession Session, bool IsNewSession)
{
SqlConnection conn = new SqlConnection(dsn);
SqlCommand SaveCmd = new SqlCommand();
SaveCmd.Connection = conn;
try
{
if (IsNewSession)
SaveCmd.CommandText = InsertStatement;
else
SaveCmd.CommandText = UpdateStatement;
SaveCmd.Parameters.Add("@ID", new Guid(key));
SaveCmd.Parameters.Add("@Data", Serialize(Session));
SaveCmd.Parameters.Add("@LastAccessed", DateTime.Now.ToString());
conn.Open();
SaveCmd.ExecuteNonQuery();
}
finally
{
if (conn != null)
conn.Close();
}
}
private Byte[] Serialize(mySession Session)
{
if (Session == null) return null;
Stream stream = null;
Byte[] state = null;
try
{
IFormatter formatter = new BinaryFormatter();
stream = new MemoryStream();
formatter.Serialize(stream, Session);
state = new Byte;
stream.Position = 0;
stream.Read(state, 0, (int)stream.Length);
stream.Close();
}
finally
{
if (stream != null)
stream.Close();
}
return state;
}
SessionPage类和与它相干的类被封装在SessionUtility组件中。在一个新ASP.NET项目中,需求作SessionUtility组件的援用,为了与传统的ASP代码同享对话,每一个页面由SessionPage取代Page类衍生出来。一旦移植完成了,新使用法式能经由过程申明SessionPage类中界说的对话变量切换回利用本来的HttpSession对象来显示根基的HttpSession。ASP完成
本来的ASP对话只能将对话数据保留在内存中。为了将对话数据保留到SQL Server,需求写一个自界说的Visual Basic 6.0 COM对象取代如今的对话对象来办理对话形态。该COM对象在每一个Web恳求入手下手时被初始化,并从SQL Server从头载入对话数据。ASP剧本完成时,该对象将终止并把对话形态将前往到SQL Server。
Visual Basic 6 COM Session对象的次要目标是供应对微软Internet信息办事器(IIS)外部对象的会见。Visual Basic 6 COM对话对象利用SessionUtility组件的mySession类来保留对话形态,SessionUtility的SessionPersistence类用于载入和保留对话数据到SQL Server。利用regasm.exe东西将mySession和 SessionPersistence类作为COM对象表露。regasm.exe东西可以注册并为COM客户端创立一个类型库来利用框架组件类。
在对象的机关函数中形态信息被从头载入。机关函数(class_initialize)起首从Application对象中检索对话cookie、对话超时设置(SessionTimeOut)、数据库毗连字符串(SessionDSN),并创立mySession类的一个实例来坚持对话数据。接着机关函数将试图从头利用给定的cookie从SQL Server中载入对话数据。假如SQL Server中没有对话信息,或对话已终止,将发生一个新的cookie。假如SQL Server前往了对话形态数据,对话形态信息将保留在mySession对象中。
Private Sub Class_Initialize()
On Error GoTo ErrHandler:
Const METHOD_NAME As String = "Class_Initialize"
Set mySessionPersistence = New SessionPersistence
Set myObjectContext = GetObjectContext()
mySessionID = ReadSessionID()
myDSNString = GetConnectionDSN()
myTimeOut = GetSessionTimeOut()
myIsNewSession = False
Call InitContents
Exit Sub
ErrHandler:
Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
End Sub
Private Sub InitContents()
On Error GoTo ErrHandler:
Const METHOD_NAME As String = "InitContents"
If mySessionID = "" Then
Set myContentsEntity = New mySession
mySessionID = mySessionPersistence.GenerateKey
myIsNewSession = True
Else
Set myContentsEntity =mySessionPersistence.LoadSession(mySessionID, myDSNString, myTimeOut)
End If
Exit Sub
ErrHandler:
Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
End Sub
假如对象实例超越了剧本的局限,将履行解构函数(class_terminate)。解构函数将利用SessionPersistence.SaveSession()办法坚持对话数据。假如是一个新对话,解构函数将新cookie发送回阅读器。
Private Sub Class_Terminate()
On Error GoTo ErrHandler:
Const METHOD_NAME As String = "Class_Terminate"
Call SetDataForSessionID
Exit Sub
ErrHandler:
Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
End Sub
Private Sub SetDataForSessionID()
On Error GoTo ErrHandler:
Const METHOD_NAME As String = "SetDataForSessionID"
Call mySessionPersistence.SaveSession(mySessionID,
myDSNString, myContentsEntity, myIsNewSession)
If myIsNewSession Then Call WriteSessionID(mySessionID)
Set myContentsEntity = Nothing
Set myObjectContext = Nothing
Set mySessionPersistence = Nothing
Exit Sub
ErrHandler:
Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
End Sub
例程
例程设计为增添并显示一个数字。不论载入了哪一个页面,因为数字值保留在SQL Server中并在ASP和ASP.NET间同享,数字将不休增添。
创立例程的步调
1. 创立一个新数据库SessionDemoDb。
2. 创立新表SessState(osql.exe -E -d SessionDemoDb -i Session.sql)。
3. 创立新虚拟目次Demo。
4. 在ASP设置装备摆设页中封闭ASP对话。
5. 将web.config、testPage.aspx、Global.asa、testPage.asp和GlobalInclude.asp复制到虚拟目次。
6. 更新Global.asa和web.config中的DSN字符串设置。对话超时设置是可选的,默许为20分钟。
7. 将SessionUtility.dll装置到全局组件缓存(gacutil /i SessionUtility.dll)。
8. 利用regasm.exe把SessionUtility.dll作为COM对象表露(regasm.exe SessionUtility.dll /tlb:SessionUtility.tlb)。
9. 将SessionManager.dll复制到当地目次并利用regsvr32.exe注册(regsvr32 SessionManager.dll)。
10. 付与IUSR_<盘算机名>帐户读取和运转会见SessionMgr.dll的权限。
运转例程的步调
1. 翻开微软Internet Explorer。
2. 为传统的ASP中载入testPage.asp。数字"1"将呈现在Web页中。
3. 点击Internet Explorer的刷新来从头载入该页面。数字将增添。
4. 为ASP.NET改动URL为testPage.aspx。数字依然增添。
5. 假如利用testPage.aspx入手下手,进程不异。
在存在的ASP使用法式中拔出COM对象
开辟ASP使用法式的一个凡是的习气是在每一个剧本入手下手时包括一个文件来同享代码和常量。拔出自界说对话对象的最初路子是在私有包括文件中到场示例代码。最初一步复杂地利用自界说对话变量名取代了一切到对话对象的援用。
限制/改善
本计划不撑持在Session对象中保留了COM对象的ASP使用法式。在这类情形下,为了利用自界说对话对象,需求一个自界说的调剂器来串行化/并行化形态。另外,本计划也不撑持保留字符串类型数组。做一些附加任务可以完成该特征:利用Visual Basic 6.0的Join函数在保留到对话对象前将数组元素毗连成一个字符串,反向操作可使用Visual Basic 6.0的Split函数将字符串分化为自力的数组元素。在.NET框架组件中,Join和Split办法使String类的成员。
结论
ASP.NET提出了新的编程典范和系统布局,并供应了很多比传统ASP的优点。虽然将ASP移植到ASP.NET的进程不复杂,ASP.NET更好的编程模子和更高的功能将使转换进程值得。除在Session对象中保留COM对象的特例,本文会商的路子供应了一个复杂完成迁徙的处理计划。
Windows本身的所有问题都会一成不变的也累加到了它的身上。安全性、稳定性、跨平台性都会因为与NT的捆绑而显现出来; 完全不知道到底自己学的是什么。最后,除了教程里面说的几个例子,还是什么都不会。 不是很难但是英文要有一点基础网上的教程很少有系统的详细的去买书吧,另不用专门学习vb关于vbscript脚本在asp教材都有介绍 我们必须明确一个大方向,不要只是停留在因为学而去学,我们应有方向应有目标. 从事这个行业,那么你可以学ASP语言,简单快速上手,熟练dreamweav排版,写asp代码,熟练photoshop处理图片,打好基础就行了 它可通过内置的组件实现更强大的功能,如使用A-DO可以轻松地访问数据库。 它可通过内置的组件实现更强大的功能,如使用A-DO可以轻松地访问数据库。 运用ASP可将VBscript、javascript等脚本语言嵌入到HTML中,便可快速完成网站的应用程序,无需编译,可在服务器端直接执行。容易编写,使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行。 那么,ASP.Net有哪些改进呢? 你可以通过继承已有的对象最大限度保护你以前的投资。并且C#和C++、Java一样提供了完善的调试/纠错体系。 代码的可重用性差:由于是面向结构的编程方式,并且混合html,所以可能页面原型修改一点,整个程序都需要修改,更别提代码重用了。 弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。 ASP.Net摆脱了以前ASP使用脚本语言来编程的缺点,理论上可以使用任何编程语言包括C++,VB,JS等等,当然,最合适的编程语言还是MS为.NetFrmaework专门推出的C(读csharp),它可以看作是VC和Java的混合体吧。 封装性使得代码逻辑清晰,易于管理,并且应用到ASP.Net上就可以使业务逻辑和Html页面分离,这样无论页面原型如何改变,业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高。 ASP主要是用好六个对象,其实最主要的是用好其中两个:response和request,就可以随心所欲地控制网页变换和响应用户动作了。 下面简单介绍一下我学习ASP的方法,希望对想学习ASP的朋友有所帮助... 在平时的学习过程中要注意现学现用,注重运用,在掌握了一定的基础知识后,我们可以尝试做一些网页,也许在开始的时候我们可能会遇到很多问题,比如说如何很好的构建基本框架。 ASP.Net和ASP的最大区别在于编程思维的转换,而不仅仅在于功能的增强。ASP使用VBS/JS这样的脚本语言混合html来编程,而那些脚本语言属于弱类型、面向结构的编程语言,而非面向对象,这就明显产生以下几个问题: ASP的语言不仅仅只是命令格式差不多,而是包含在<%%>之内的命令完全就是VB语法。虽然ASP也是做为单独的一个技术来提出的,但他就是完全继承了VB所有的功能。 没有坚实的理论做基础,那么我们连踏入社会第一步的资本都没有,特别对于计算机专业的学生学好专业知识是置关重要的。在这里我侧重讲一下如何学习ASP,从平时的学习过程中。
页:
[1]