greatwang

  博客园 :: 首页 :: 联系 :: 订阅 订阅 :: 管理
  5 Posts :: 8 Stories :: 2 Comments :: 0 Trackbacks

2008年6月6日 #

本文重点对实现控件事件的基本概念进行介绍,这些概念对于帮助开发人员为服务器控件创建事件有着重要意义。

  1. 事件基本概念

  事件是当有动作发生或者状态改变时,类发出的信息或者通知。通常情况下,状态的发生或者改变由用户界面动作初始化,例如,单击按钮,或者由于其他的程序逻辑引起。产生事件的类或者说发送通知的类叫做事件源sender,接收事件的类叫做事件接收者receiver。二者之间通过委托(delegate)实现关联。下面列举了一段常见的应用事件代码。

// 声明事件
ClickcustomControl.Click += new EventHandler(this.customControl1_Clicked);
// 实现事件处理程序
customControl1_Clicked(object sender,EventArgs e){......}

  如上代码列举了服务器控件声明事件和实现事件处理程序的过程。由于这个过程非常简单,在此将不多做解释。另外,在实际应用中,开发人员通过为服务器控件实现事件机制,可以不采用以上的声明事件方式,而是在控件声明标记中仅仅列出"OnClick = customControl1_Clicked"即可。实际上,事件的声明和具体事件处理程序的实现都是比较简单易用的。然而,为控件实现事件机制却不是一件容易的事情。

  从服务器控件开发的角度而言,控件事件(仅指服务器端事件,而不包括客户端事件)可能来自两个方面:一是从基类继承的事件。例如,假设自定义控件从Button类继承,那么该控件将继承基类的Click事件。二是根据开发需求而创建的自定义事件。下面分别对这两种事件进行介绍。

  2. 实现从基类继承的事件

  众所周知,自定义服务器控件归根结底是从System.Web.UI.Control派生而来。该基类中已经定义了一些事件。因此,在创建服务器控件过程中,很可能需要重写以下继承的多个事件。

  ·DataBinding事件:该事件当服务器控件绑定到数据源时发生,其对应事件处理程序为OnDataBinding。

  ·Disposed事件:该事件当从内存释放服务器控件资源时发生,其对应的事件处理程序为OnDisposed。这是服务器控件生命周期的的最后阶段。

  ·Init事件:该事件当服务器控件初始化时发生,其对应的事件处理程序为OnInit。Init事件是控件生命周期的第一步。

  ·Load事件:该事件当服务器控件加载到Page对象中时发生,其对应的事件处理程序为OnLoad。

  ·PreRender事件:该事件在加载Control对象之后、呈现之前发生,其对应的事件处理程序为OnPreRender。

  ·Unload事件:该事件当服务器控件从内存中卸载时发生,其对应的事件处理程序为OnUnload。

  以上内容针对Control基类的几个事件进行了简要说明。由于服务器控件均继承自Control基类(WebControl也是继承自Control类),因此,开发人员完全可以重写事件所对应的事件处理程序,这样便可以实现一些自定义内容。

  若要实现自定义继承的事件,需要重写从基类继承的受保护的OnEventName方法,而不必附加委托(EventHandler)。通常情况下,重写的事件处理程序应该调用基类的OnEventName方法,以确保调用附加到事件的委托(除非不想调用这些委托)。以下代码片段说明自定义控件重写继承的DataBinding事件的处理过程。

protected override void OnDataBinding(EventArgs e)
{
 //添加一些自定义逻辑代码
 //调用基类方法
 base.OnDataBinding(e);
}

  如上代码所示,在重写事件处理程序OnDataBinding过程中,首先需要添加一些根据应用需求而实现的自定义逻辑代码,然后,一定要牢记需调用基类方法。

  以上内容对Control基类的事件和派生类重写对应事件处理程序的过程进行了介绍。需要读者注意的是,上文并非说明自定义服务器控件仅能够重写以上几个来自Control基类事件的事件处理程序。如果自定义控件继承自其他原本带有事件的基类,例如,Button、DataList等(归根到底,它们也是从Control基类继承),那么继承的事件处理程序仍然可以被重写,例如,继承自Button类的控件自然获得Click事件,并且可以重写OnClick事件处理程序。
3. 创建自定义服务器控件事件

  在介绍创建自定义服务器控件事件的方法之前,我们首先来简单回顾一下相关的事件模型

  在Web窗体页面中,与服务器控件关联的事件由客户端引发并由Web服务器处理(注意:事件必须称为"引发",而不要使用"触发"和"激发"等词,它们都是不准确,不规范的)。对于在客户机上由服务器控件引发的事件,ASP.NET 2.0事件模型收集有关请求的信息,并使用HTTP Post将详细信息传递到服务器。服务器上的Page Framework对该公告作出解释以确定发生的事件,然后,调用适当的处理程序方法。下图1简单说明了这一过程。


图1

  如图1所示,在客户端计算机中,用户单击购物车的Add(添加)按钮,试图将所选商品放入购物车中。在单击之后,事件模型收集了相关信息,例如,Submit = btnAddToCart,Prod3 = Gizmo等等,将这些信息通过Post方式传递到服务器。服务器在接收这些信息后,首先对其进行分析,然后,调用事件处理程序btnAddToCart(obj,event)进行处理。以上就是基本的事件处理模型。

  对于普通应用程序开发人员而言,只需要实现控件的事件处理程序即可,更进一步的信息对于他们而言是隐藏的,而且也是没有必要作更多关心的。然而,作为服务器控件开发人员,则必须仔细考虑这一事件处理模型。

  如果读者仔细思考以上过程,则会发现两个在事件处理模型中需要解决的重要问题。第一,服务器端如何捕获回传的单击事件,第二,通过Post方式回传到服务器端的数据,具体是如何处理的。以上两个问题至关重要。如果能够解决好这两个问题,那么创建自定义服务器控件事件则变得非常容易。

  为了解决以上问题,ASP.NET 2.0提供了两个重要接口:IPostBackEventHandler和IPostBackDataHandler。IPostBackEventHandler接口用于处理由客户端引发的页面回传的事件。实现此接口,服务器控件可将客户端的提交表单事件对应到服务器端的事件上,并且通过事件处理程序完成对该客户端事件的处理。IPostBackDataHandler接口用于检查提交给页面的数据,并确定是否在客户端修改过。当控件实现该接口,控件则自动具有了参与回传数据的处理能力。开发人员可以通过实现接口相关成员,完成针对回传数据的处理逻辑。

  实际上,ASP.NET 2.0中绝大多数服务器控件都引发从客户端到服务器的回传,并且读者实现的很多服务器控件也必须引发回传。因此,以上两个接口对于实现控件事件非常重要。对于它们,本节仅简单介绍一下。在随后的文章中,读者将通过典型示例,详细了解实现接口成员,捕获回传事件,处理回传数据的具体方法。

  另外,ASP.NET 2.0增强了有关回调处理方面的功能。例如,使用System.Web.UI.ICallbackEventHandler接口和Page.GetCallbackEventReference方法等。通过这些对象的应用可实现在客户端运行服务器端代码,从而避免丢失客户端状态并且不导致服务器往返的处理开销。这些内容与服务器控件事件之间有着一些联系。然而,由于回调应用在服务器控件中应用较少。因此,将不作过多说明。

  4. 小结

  从技术发展的角度来讲,ASP.NET技术从1.x升级到2.0版本,在服务器控件事件开发方面没有任何明显的修改。如果读者已经了解了ASP.NET 1.x下创建服务器控件事件的内容,那么可以按照过去1.x的方法和思路进行开发。下面一篇文章,笔者将通过典型示例介绍服务器控件捕获回传事件的实现方法。
posted @ 2008-06-06 10:19 great wang 阅读(39) | 评论 (0)编辑

创建Asp.net里的服务器控件和Windows Form的控件一样,也有几种方式:

  1、 用户控件(user control)

  2、 从Control、WebControl派生的自定义控件

  3、 从已有的Asp.net服务器控件扩展

  用户控件以.ascx为扩展名,并保存为文本文件,用户控件不像从Control和WebControl派生下来的服务器控件那样需要预编译,当用户控件在.aspx页面中使用的时候,页面解析器从.aspx文件中动态地生成一个类,并且将其编译到一个装配件中。其优点有:解决了代码复用,同时每一个用户控件有自己的对象模型,其编写语言和.aspx页面的语言无关。

  从已有的Asp.net服务器控件扩展,主要是对.net原生的服务器控件的功能加强以适用我们开发和最终用户的需要。

  从Control、WebControl派生的自定义控件以编译过的类库形式部署的。

  上述的1和3在本系列中将不做讲解,在本系列中只讲解从Control、WebControl派生的服务器控件。

  我们要编写一个自定义控件,只要从Control、WebControl继承即可,Control已经实现了IComponent接口,而WebControl本身又是从Control上派生下来的,因而他们也支持组件的可视化设计。

  Render方法和HtmlTextWriter类,当我们从一个Control类派生一个Asp.net服务器控件时,Control类为我们提供了可重载的Render和一个HtmlTextWriter类型的实例,Render方法就是将服务器控件内容发送到提供的 HtmlTextWriter 对象,而HtmlTextWriter封装了HTML写文本流的功能函数。

using System;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary1
{
 public class Control1 : System.Web.UI.Control
 {
  protected override void Render(System.Web.UI.HtmlTextWriter writer)
  {
   writer.Write("I'm here.");
  }
 }

 public class Control2 : System.Web.UI.WebControls.WebControl
 {
  protected override void Render(System.Web.UI.HtmlTextWriter writer)
  {
   writer.Write("I'm here too.");
  }
 }
}

  上面的代码里我们定义了一个Contro1和Control2,他们分别从Control和WebControl继承下来,那他们之间到底有什么样的本质区别呢?先看下面的效果:

 

  从上面的效果我们不难看出他们之间有什么区别,WebControl类通过属性提供了对样式的支持,比如字体、高度、背景色等等。那我们什么时候来选择从Control派生,什么时候又选择从WebControl派生呢?如果控件要生成非可视化的元素或显示给非HTML客户端,就从Control派生,如SqlDataSource;如果要提供客户端生成可视化的HTML,那我们就从WebControl派生,如TextBox。
posted @ 2008-06-06 10:01 great wang 阅读(32) | 评论 (0)编辑

利用ASP.NET 2.0技术,创建Web自定义服务器控件并不是一件轻松的事情。因为,这需要开发人员了解并能够灵活应用多种Web开发技术,例如,CSS样式表、客户端脚本语言、.NET开发语言、服务器控件开发技术,甚至是当前最火的AJAX技术等等。虽然现实如此"艰难",但是这种开发技术也不是真的难到不可掌握。事事都要从头做起。本文将针对利用ASP.NET 2.0技术,创建Web自定义服务器控件的基础知识进行详细介绍,内容包括:服务器控件概念、控件类型、生命周期等。

  1. 什么是Web服务器控件

  在ASP.NET 2.0中,Web服务器控件是指在服务器上执行程序逻辑的组件。这个组件可能生成一定的用户界面,也可能不包括用户界面。每个服务器控件都包含一些成员对象,以便开发人员调用,例如,属性、事件、方法等。

  通常情况下,服务器控件都包含在ASP.NET页面中。当运行页面时,.NET执行引擎将根据控件成员对象和程序逻辑定义完成一定的功能。例如,在客户端呈现用户界面。这时,用户可与控件发生交互行为,当页面被用户提交时,控件可在服务器端引发事件,并由服务器端根据相关事件处理程序来进行事件处理。服务器控件是WebForm编程模型的重要元素,它们构成了一个新的、基于控件的表单程序的基础。通过这种方式可以简化Web应用程序的开发,提高应用程序的开发效率。

  服务器控件的广泛应用,简化了应用程序的开发,提高了工作效率。那么,何时应创建并使用自定义服务器控件呢?下面列举了在三种具体适用情况:

  (1)某个现有服务器控件基本符合应用要求,但是,缺少某些特殊的功能,这时可以通过从现有控件中派生并重写其属性、方法或事件来自定义服务器控件。

  (2)需要使用的服务器控件结合了两个或多个现有控件的功能,例如,封装一个按钮和一个文本框的复合控件。此时可以通过创建服务器控件达到这一目的。

  (3)现有服务器控件(或其组合)均不符合应用的要求。对于这种情况,可以通过从基类派生的方式来创建自定义服务器控件。

  2 服务器控件的类型

  ASP.NET 2.0提供了多种服务器控件。根据服务器控件定义方式,可分为以下3种类型:HTML服务器控件、ASP.NET标准服务器控件和自定义服务器控件。

  (1)HTML服务器控件

  HTML服务器控件派生自名字空间System.Web.UI.HtmlControls。它们由普通HTML控件(指HTML语言已定义的控件,例如,Button、Input等)转换而来,其呈现的输出,基本上与普通HTML控件一致。默认情况下,服务器端很难控制Web页面上的普通HTML控件,但是,通过将普通HTML控件转换为HTML服务器控件的方法,开发人员则能够轻而易举对其进行编程控制。

  将普通HTML控件转换为HTML服务器控件方法比较简单。一般情况下,通过两个步骤完成转换:

  (1)在普通HTML控件特性中添加Runat="Server"属性;

  (2)设置ID属性。通过转换,普通HTML控件的相关属性、事件、方法等将全部映射到HTML服务器控件中,由此,通过编程即可在页面处理过程中引用并控制该HTML服务器控件。

  HTML服务器控件具有以下几个重要特点:

  一、可在服务器上使用面向对象技术对其进行编程控制,这为编程开发提供了便利。

  二、自动维护视图状态。在页面窗体到服务器端往返期间,用户在HTML服务器控件中输入的值将在页面回传中自动维护。

  三、与验证控件进行交互,便于验证用户是否在控件输入了适当的信息。

  四、允许在HTML服务器控件中自定义属性。开发人员可以将任何需要的属性添加到HTML服务器控件的属性集中,页框架将读取并呈现它们而不更改其他任何功能。

  (2)ASP.NET标准服务器控件

  ASP.NET标准服务器控件均在名字空间System.Web.UI.WebControls中定义。所谓"标准"是指这类服务器控件内置于ASP.NET 2.0框架中,是预先定义的。这类控件并不一对一映射到HTML服务器控件,它们比HTML服务器控件具有更加丰富的功能,并且更加抽象。

  与ASP.NET 1.x相比,ASP.NET 2.0新增了50多个标准服务器控件。按照控件所提供的功能,ASP.NET标准服务器控件可分为以下6种类型:

  (1)标准控件:主要是指传统的Web窗体控件,例如TextBox、Button、Panel等控件。它们有一组标准化的属性、事件和方法,因此能够使开发工作变得简单易行。

  (2)数据控件:该类控件可细分为两种类型:数据源控件和数据绑定控件。数据源控件主要实现数据源连接、SQL语句/存储过程执行,返回数据集合等功能。具体包括SqlDataSource、AccessDataSource、XmlDataSource、SiteMapDataSource、ObjectDataSource等。数据绑定控件包括Repeater、DataList、GridView、DetailsView、FormView等。这类控件主要实现数据显示、提供编辑、删除等相关用户界面等。通常情况下,首先,需要使用数据源控件连接数据库,并返回数据集合,然后,利用数据绑定控件实现数据显示、更新、删除等功能。由于Visual Studio 2005设计时的强大支持下,开发人员可以快速实现以上功能,甚至不需要编写一行代码。

  (3)验证控件:它们是一组特殊的控件,控件中包含验证逻辑以测试用户输入。具体包括:RequiredFieldValidator、RangeValiedator、RegularExpressionValidator、CompareValidator等等。开发人员可以将验证控件附加到输入控件,测试用户对该输入控件输入的内容。验证控件可用于检查输入字段,对照字符的特定值或模式进行测试,其目的是验证某个值是否在限定范围之内或者其他逻辑。

  (4)站点导航控件:该类控件可与站点导航数据结合,实现站点导航功能。具体包括:Menu、SiteMapPath、TreeView。对于大型站点,站点导航控件都有着广泛应用前景。

  (5)WebParts控件:Web部件是一项非常了不起的功能,利用它能够创建具备高度个性化特征的Web应用程序。实现Web部件功能需要WebParts控件支持,ASP.NET 2.0提供了以下相关控件,例如WebPartManager、WebPartZone、EditorZone、CatalogZone、PageCatalogPart、AppearanceEditorPart等等。

  (6)登录控件:这类控件可快速实现用户登录及相关功能,例如,显示登录状态、密码恢复、创建新用户等。具体包括:LoginView、Login、CreateUserWizard、LoginStatus等等。

  ASP.NET标准服务器控件由于是官方提供,因此,从系统内部就提供了对它们的强大支持。对于开发人员而言,这些控件是构建Web应用程序的主力军。

  (3)自定义服务器控件

  自定义服务器控件派生自名字空间System.Web.UI.Control或System.Web.UI.WebControls。这种服务器控件完全由开发人员自行设计开发,开发人员可自定义UI、功能、属性、方法、事件等特征,这是自定义服务器控件与ASP.NET标准服务器控件本质的区别。

  常见的自定义服务器控件分为4种:复合控件、验证控件、模板控件和数据绑定控件。

  (1)复合控件:该类控件包含两个或多个已存在控件。它复用了子控件提供的实现来进行控件呈现、事件处理及其他功能。

  (2)验证控件:与上文所述标准服务器控件中的验证控件定义相同。

  (3)模板控件:该类控件提供了一种称为模板的通用功能。模板控件本身不提供用户界面,而是通过内联模板提供,这意味着模板控件允许页面开发人员自定义该控件的用户界面。

  (4)数据绑定控件:与上文所述标准服务器控件中的数据绑定控件定义相同。

  另外,除了以上4类控件之外,自定义服务器控件具有以下特点:

  (1)灵活性强:开发人员可以根据应用需要,自定义其中的UI、功能、属性、方法和事件等。

  (2)样式支持:由于自定义服务器控件可能派生自System.Web.UI.WebControls,因此通过继承的Style属性可定义样式,例如字体、高度、宽度、颜色等。

  (3)提供对标准服务器控件的扩展功能:自定义服务器控件可在继承标准服务器控件的基础上,扩展或改进相关属性、方法、功能等,甚至可以将不同的服务器控件组合起来,形成复合控件。

   (4)易于部署:具有"即插即用"的特征,开发人员只要将编译好的自定义服务器控件复制到相关的bin目录即可使用。

  (5)难于创建:开发自定义服务器控件需要开发人员员精通多方面技术,同时,还需要耗费大量的精力和时间。

  3、服务器控件生命周期简介

  服务器控件的生命周期是创建服务器控件最重要的概念。作为开发人员,必须对服务器控件生命周期深刻理解。当然,这不是一朝一夕就可以做到的。对于学习控件开发技术的初学者,可以不必掌握得非常详细深入,只需对服务器控件的生命周期中的不同阶段有一个大致的了解即可。

  在掌握服务器控件生命周期的过程中,读者要特别注意有关服务器控件状态的相关内容。在重点了解生命周期各个阶段的同时,对服务器控件的状态变化要注意以下问题:控件的生命周期何时保存控件和恢复其状态;何时与页面及其他控件之间进行交互;何时执行重要的处理逻辑;在各个阶段,控件可使用哪些信息、保持哪些数据、控件呈现时处于哪种状态以及何时输出显示标记文本等。如下列举了服务器控件生命周期所要经历的11个阶段。

  (1)初始化----在此阶段中,主要完成两项工作:一、初始化在传入Web请求生命周期内所需的设置;二、跟踪视图状态。首先,页面框架通过默认方式引发Init事件,并调用OnInit()方法,控件开发人员可以重写该方法为控件提供初始化逻辑。此后,页面框架将调用TrackViewState方法来跟踪视图状态。需要注意的是:多数情况下,Control基类提供的TrackViewState方法实现已经足够了。只有在控件定义了复杂属性时,开发人员才可能需要重写TrackViewState方法。

  (2)加载视图状态----此阶段的主要任务是检查服务器控件是否存在以及是否需要将其状态恢复到它在处理之前的请求结束的状态。因此该过程发生在页面回传过程中,而不是初始化请求过程。在此阶段,页面框架将自动恢复ViewState字典。如果服务器控件不维持其状态,或者它有能力通过默认方式保存其所有状态而使用ViewState字典,那么开发人员则不必实现任何逻辑。针对那些无法在ViewState字典中存储的数据类型或者需要自定义状态管理的情况,开发人员可以通过重写LoadViewState方法来自定义状态的恢复和管理。

  (3)处理回发数据----若要使控件能够检查客户端发回的窗体数据,那么必须实现System.Web.UI.IPostBackDataHandler接口的 LoadPostData()方法。因此只有处理回发数据的控件参与此阶段。

  (4)加载----至此阶段开始,控件树中的服务器控件已创建并初始化、状态已还原并且窗体控件反映了客户端的数据。此时,开发人员可以通过重写OnLoad()方法来实现每个请求共同的逻辑。

  (5)发送回发更改通知----在此阶段,服务器控件通过引发事件作为一种信号,表明由于回发而发生的控件状态变化(因此该阶段仅用于回发过程)。为了建立这种信号,开发人员必须再次使用System.Web.UI.IPostBackDataHandler接口,并实现另一方法-RaisePostBackChangedEvent()。其判断过程为:如果控件状态因回发而更改,则LoadPostData()返回true;否则返回false。页面框架跟踪所有返回true的控件并在这些控件上调用RaisePostDataChangedEvent()。

  (6)处理回发事件----该阶段处理引起回发的客户端事件。为了便于将客户端事件映射到服务器端事件上进行处理,开发人员在此阶段可以通过实现System.Web.UI.IPostBackEventHandler接口的RaisePostBackEvent()方法来实现该逻辑。由此途径,服务器控件将成功捕获回发的客户端事件进行服务器端的相应处理。

  (7)预呈现----该阶段完成在生成控件之前所需要的任何工作。通常情况下是通过重写OnPreRender()方法完成该工作。需要注意的是:在该阶段,可以保存在预呈现阶段对控件状态所做的更改,而在呈现阶段进行的更改则会丢失。

  (8)保存状态----如果服务器控件不维持状态,或者它有能力通过默认方式保存其所有状态而使用ViewState字典,那么开发人员不必在该阶段实现任何逻辑。因为这个保存状态的过程是自动的。如果服务器控件需要自定义状态保存,或者控件无法在ViewState字典中存储特殊的数据类型,则需要通过重写SaveViewState()方法来实现状态保存。

  (9)呈现----表示向HTTP输出流中写入标记文本的过程。开发人员通过重写Render()方法使其在输出流上自定义标记文本。

  (10)处置----在此阶段中,通过重写Dispose ()方法完成释放对昂贵资源的引用,如数据库链接等。

  (11)卸载----完成的工作与"处置"阶段相同,但是,开发人员通常在Dispose()方法中执行清除,而不处理Unload事件。

  4、小结

  服务器控件在ASP.NET 2.0框架中起着举足轻重的作用,是构建Web应用程序最关键、最重要的组成元素。对于一个优秀的开发人员,掌握服务器控件的基础知识是非常重要的。本文就服务器控件的概念、类型、生命周期等关键内容进行了介绍。希望读者能够将这些内容牢固掌握,为写出精彩的服务器控件打下良好的基础。
posted @ 2008-06-06 09:58 great wang 阅读(89) | 评论 (0)编辑

      在web开发时,有的系统要求同一个用户在同一时间只能登录一次,也就是如果一个用户已经登录了,在退出之前如果再次登录的话需要报错。 如下文章是一种常见的做法,但是有些影响服务器性能,拿出来(转:http://dev.yesky.com/187/7680687.shtml#pls)大家讨论一下:

  常见的处理方法是,在用户登录时,判断此用户是否已经在Application中存在,如果存在就报错,不存在的话就加到Application中(Application是所有Session共有的,整个web应用程序唯一的一个对象):

以下是引用片段:
  string strUserId = txtUser.Text;
  ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
  if (list == null)
  {
  list = new ArrayList();
  }
  for (int i = 0; i < list.Count; i++)
  {
  if (strUserId == (list[i] as string))
  {
  //已经登录了,提示错误信息
  lblError.Text = "此用户已经登录";
  return;
  }
  }
  list.Add(strUserId);
  Application.Add("GLOBAL_USER_LIST", list);

  当然这里使用Cache等保存也可以。

  接下来就是要在用户退出的时候将此用户从Application中去除,我们可以在Global.asax的Session_End事件中处理:

以下是引用片段:
  void Session_End(object sender, EventArgs e)
  {
  // 在会话结束时运行的代码。
  // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
  // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
  // 或 SQLServer,则不会引发该事件。
  string strUserId = Session["SESSION_USER"] as string;
  ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
  if (strUserId != null && list != null)
  {
  list.Remove(strUserId);
  Application.Add("GLOBAL_USER_LIST", list);
  }
  }

  这些都没有问题,有问题的就是当用户直接点浏览器右上角的关闭按钮时就有问题了。因为直接关闭的话,并不会立即触发Session过期事件,也就是关闭浏览器后再来登录就登不进去了。

  这里有两种处理方式:

  1、使用Javascript方式

  在每一个页面中加入一段javascript代码:

以下是引用片段:
  function window.onbeforeunload()
  {
  if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey){
  window.open("logout.aspx");
  }
  }

  由于onbeforeunload方法在浏览器关闭、刷新、页面调转等情况下都会被执行,所以需要判断是点击了关闭按钮或是按下Alt+F4时才执行真正的关闭操作。

  然后在logout.aspx的Page_Load中写和Session_End相同的方法,同时在logout.aspx中加入事件:onload="javascript:window.close()"

  但是这样还是有问题,javascript在不同的浏览器中可能有不同的行为,还有就是当通过文件->关闭时没有判断到。

  2、使用xmlhttp方法(这种方法测试下来没有问题)

  在每个页面中加入如下的javascript(这些javascript也可以写在共通里,每个页面引入就可以了)

以下是引用片段:
  var x=0;
  function myRefresh()
  {
  var httpRequest = new ActiveXObject("microsoft.xmlhttp");
  httpRequest.open("GET", "test.aspx", false);
  httpRequest.send(null);
  x++;
  if(x<60) //60次,也就是Session真正的过期时间是30分钟
  {
  setTimeout("myRefresh()",30*1000); //30秒
  }
  }
  myRefresh();

  在web.config中设置

以下是引用片段:
<sessionState mode="InProc" timeout="1"></sessionState> 

  test.aspx页面就是一个空页面,只不过需要在Page_Load中加入:

以下是引用片段:
  Response.Expires = -1;

  保证不使用缓存,每次都能调用到这个页面。

  原理就是:设置Session的过期时间是一分钟,然后在每个页面上定时每30秒连接一次测试页面,保持Session有效,总共连60次,也就是30分钟。如果30分钟后用户还没有操作,Session就会过期。当然,如果用户直接关闭浏览器,那么一分钟后Session也会过期。这样就可以满足要求了。

posted @ 2008-06-06 09:45 great wang 阅读(58) | 评论 (1)编辑

URL映射ASP.NET 2.0中提供的新特性。URL映射技术帮助我们将一个特定URL映射为另一个URL。为了帮助理解,我们假设你在站点有一个叫Homepage.aspx的页面来访问主页,所有的用户也都用这个页面来访问你的主页。但由于某些原因,你要将主页改为OriginalHome.aspx。此时使用URL映射让你可以映射到新页面,而不必通知用户。

  如果我们设置了URL映射,那么任何用户在URL栏输入Homepage.aspx时,调用的都是OriginalHome.aspx。

  深入概念:

  让我们看看如何实现它。

  这可以在configuration部分实现。

  语法:

以下是引用片段:
<urlMappings enabled="[true|false]">   
<add url="String"    
mappedUrl="String"/>   
</urlMappings>

  如果你想使用URL映射,你必须将enabled属性设置为true。每个add元素都含有一个原URL和映射URL。对,中国自学编程网,www.zxbc.cn ,概念很简单!如果我们为上述场景配置了URL映射,config文件中的元素显示如下:

以下是引用片段:
<urlMappings enabled="true">   
<add url="~/ Homepage.aspx" mappedUrl="~/ OriginalHome.aspx"/>   
</urlMappings>

  一旦我们进行了修改或在工程的web.config文件中增加了如上的元素,任何用户试图访问Homepage.aspx时,由于URL映射,都将调用OriginalHome.aspx页面。有趣的是在URL栏中仍然仅显示Homepage.aspx。所以尽管想到内部调用/执行了OriginalHome.aspx,用户在URL栏仍见到Hopepage.aspx。

  一些优点:

  1.若你的客户标记了到一个页面的链接,但你又得删除该页并在换上其他页面,那么使用URL映射你可以解决这个商业问题而不用让客户知道这个页面变化。

  2.若有一个大而复杂的URL,但不想把它给用户,那么你可以告知简单的URL,而自己将简单的URL映射到原先的URL。

  3. 用这个方法可以方便处理菜单控件。最好的例子就是asp.net站点。

  4.这里也牵涉到安全(用户无法在URL栏看到真实的页面名,这也是一种加密!)。

  希望你喜欢这个新特性。
本文转自:http://dev.yesky.com/149/7685649.shtml

posted @ 2008-06-06 09:32 great wang 阅读(383) | 评论 (1)编辑