ASP.NET Session 实现会话的建立流程

asp.net|session

  HTTP 协议之所以能够获得如此大的成功,其设计实现的简洁性和无状态连接的高效率是很重要的原因。而为了在无状态的 HTTP 请求和有状态的客户端操作之间达到平衡,产生了服务器端会话 (Session) 的概念。客户端在连接到服务器后,就由 Web 服务器产生并维护一个客户端的会话;当客户端通过无状态 HTTP 协议再次连接到服务器时,服务器根据客户端提交的某种凭据,如 Cookie 或 URL 参数,将客户关联到某个会话上。这种思路在各种开发语言和开发环境中大量得到应用。

  在 ASP.NET 中,Web 应用程序和会话状态被分别进行维护,通过 HttpApplication 和 HttpSessionState 分离 Web 应用程序与会话的功能。应用程序层逻辑在 Global.asax 文件中实现,运行时编译成 System.Web.HttpApplication 的实例;会话则作为单独的 System.Web.SessionState.HttpSessionState 实例,由服务器统一为每个用户会话维护,通过 ASP.NET 页面编译成的 System.Web.UI.Page 对象子类的 Session 属性访问。关于 ASP.NET 中不同层次关系可参考我以前的一篇文章《.NET 1.1中预编译ASP.NET页面实现原理浅析 [1] 自动预编译机制浅析》,以下简称【文1】。
  
  ASP.NET 在处理客户端请求时,首先将根据客户端环境,生成一个 System.Web.HttpContext 对象,并将此对象作为执行上下文传递给后面的页面执行代码。
  在【文1】的分析中我们可以看到,HttpRuntime 在处理页面请求之前,根据 HttpWorkerRequest 中给出的环境,构造 HttpContext 对象,并以次对象作为参数从应用程序池中获取可用应用程序。简要代码如下:
  以下内容为程序代码:
  
  private void HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
  {
  // 构造 HTTP 调用上下文对象
  HttpContext ctxt = new HttpContext(wr, 0);
  
  //...
  
  // 获取当前 Web 应用程序实例
  IHttpHandler handler = HttpApplicationFactory.GetApplicationInstance(ctxt);
  
  // 调用 handler 实际处理页面请求
  }
  
  HttpApplicationFactory 工厂内部维护了一个可用的应用程序实例缓冲池,用户降低应用程序对象构造的负荷。
  如果池中没有可用的应用程序对象实例,此对象工厂最终会调用 System.Web.HttpRuntime.CreateNonPublicInstance 方法构造新的应用程序实例,并调用其 InitInternal 方法初始化。详细步骤分析见【文1】
  以下内容为程序代码:
  
  internal static IHttpHandler HttpApplicationFactory.GetApplicationInstance(HttpContext ctxt)
  {
  // 处理定制应用程序
  //...
  
  // 处理调试请求
  //...
  
  // 判断是否需要初始化当前 HttpApplicationFactory 实例
  //...
  
  // 获取 Web 应用程序实例
  return HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(ctxt);
  }
  
  private HttpApplication HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context)
  {
  HttpApplication app = null;
  
  // 尝试从已施放的 Web 应用程序实例队列中获取
  //...
  
  if(app == null)
  {
  // 构造新的 Web 应用程序实例
  app = (HttpApplication)System.Web.HttpRuntime.CreateNonPublicInstance(this._theApplicationType);
  
  // 初始化 Web 应用程序实例
  app.InitInternal(context, this._state, this._eventHandlerMethods);
  }
  
  return app;
  }
  
  这里的 System.Web.HttpApplication.InitInternal 函数完成对应用程序对象的初始化工作,包括调用 HttpApplication.InitModules 函数初始化 HTTP 模块(后面将详细介绍),并将作为参数传入的 HttpContext 实例保存到 HttpApplication._context 字段中。而此 HTTP 上下文对象将被后面用于获取会话对象。
  以下内容为程序代码:
  
  public class HttpApplication : ...
  {
  private HttpContext _context;
  private HttpSessionState _session;
  
  public HttpSessionState Session
  {
  get
  {
  HttpSessionState state = null;
  if (this._session != null)
  {
  state = this._session;
  }
  else if (this._context != null)
  {
  state = this._context.Session;
  }
  if (state == null)
  {
  Throw new HttpException(HttpRuntime.FormatResourceString("Session_not_available");
  }
  return state;
  }
  }
  }
  
  而在 ASP.NET 页面中获取会话的方法也是类似,都是通过 HttpContext 来完成的。
  以下内容为程序代码:
  
  public class Page : ...
  {
  private HttpSessionState _session;
  private bool _sessionRetrieved;
  
  public virtual HttpSessionState Session
  {
  get
  {
  if (!this._sessionRetrieved)
  {
  this._sessionRetrieved = true;
  try
  {
  this._session = this.Context.Session;
  }
  catch (Exception)
  {
  }
  }
  if (this._session == null)
  {
  Throw new HttpException(HttpRuntime.FormatResourceString("Session_not_enabled");
  }
  return this._session;
  }
  }
  }
  
  在 HttpContext 中,实际上是通过一个哈希表保存诸如会话对象之类信息的
  以下内容为程序代码:
  
  public sealed class HttpContext : ...
  {
  private Hashtable _items;
  
  public IDictionary Items
  {
  get
  {
  if (this._items == null)
  {
  this._items = new Hashtable();
  }
  return this._items;
  }
  }
  
  public HttpSessionState Session
  {
  get
  {
  return ((HttpSessionState) this.Items["AspSession"]);
  }
  }
  }
  
  而 HttpContext.Session 所访问的又是哪儿来的呢?这就又需要回到我们前面提及的 HttpApplication.InitModules 函数。
  
  在 .NET 安装目录 Config 子目录下的 machine.config 定义了全局性的配置信息,而 HttpApplication 就是使用其中 system.web 一节的配置信息进行初始化的。
  以下内容为程序代码:
  
  <system.web>
  <httpModules>
  <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
  <add name="Session" type="System.Web.SessionState.SessionStateModule" />
  <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
  <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
  <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
  <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
  <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
  <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </httpModules>
  </system.web>
  
  httpModules 节点指定了 HttpApplication 需要初始化的模块列表,而在前面提到的 HttpApplication.InitModules 函数正式根据此列表进行初始化的
  以下内容为程序代码:
  
  private void HttpApplication.InitModules()
  {
  HttpModulesConfiguration cfgModules = ((HttpModulesConfiguration) HttpContext.GetAppConfig("system.web/httpModules");
  
  if (cfgModules == null)
  {
  Throw new HttpException(HttpRuntime.FormatResourceString("Missing_modules_config");
  }
  _moduleCollection = cfgModules.CreateModules();
  
  for(int i = 0; i < _moduleCollection.Count; i++)
  {
  _moduleCollection[i].Init(this);
  }
  
  GlobalizationConfig cfgGlobal = ((GlobalizationConfig) HttpContext.GetAppConfig("system.web/globalization");
  if (cfgGlobal != null)
  {
  _appLevelCulture = cfgGlobal.Culture;
  _appLevelUICulture = cfgGlobal.UICulture;
  }
  }
  
  Session 节点对于的 System.Web.SessionState.SessionStateModule 对象将被 HttpModulesConfiguration.CreateModules 方法构造,并调用其 Init 函数初始化。SessionStateModule 类实际上就是负责管理并创建会话,用户完全可以自行创建一个实现 IHttpModule 接口的类,实现会话的控制,如实现支持集群的状态同步等等。
  SessionStateModule.Init 方法主要负责 machine.config 文件中的 ses

时间: 2024-11-01 02:23:57

ASP.NET Session 实现会话的建立流程的相关文章

通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[上]:采用管道处理请求

之所以称ASP.NET Core是一个Web开发平台,而不是一个单纯的开发框架,源于它具有一个极具扩展性的请求处理管道,我们可以通过对这个管道的定制来满足各种场景下的HTTP处理需求.ASP. NET Core应用的很多特性,比如路由.认证.会话.缓存等,都是通过对管道的定制来实现的.我们甚至可以通过管道定制在ASP.NET Core平台上创建我们自己的Web框架,实际上MVC和SingalR这两个重要的Web框架也是采用这样的方式创建的. [本文已经同步到<ASP.NET Core框架揭秘>

asp.net session配置入门篇

首先,session其虽然是基于cookie的,同时只对本次会话来产生效果,(原理很简单,就是字典内保存一个字典,外层字典的key也就是asp_netsessionId是由.NET自动分配的并保存到只对本次会话有效的cookie中,我们的工作只是负责内部我们需要的字典的内容,并有.NET自动分配一块区域保存起来,当然这个是有一定的时效性的,模拟代码可以看看资料,或者反编译下看看,很简单,这里就不说了)但是有时候我们就会发现默认的session存储方式,可能造成数据的丢失,虽然他的存储类型是obj

ASP.NET Session丢失原因和应对策略

正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: <sessionState mode='InProc' stateConnectionString='tcpip=127.0.0.1:424

asp.net session丢失的解决方法

现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: < sessionState mode='InProc' stateConnectionString='tcpip=127.0.0.1:42424' sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' time

[ASP.NET] Session 详解

asp.net|session|详解 阅读本文章之前的准备 阅读本文章前,需要读者对以下知识有所了解.否则,阅读过程中会在相应的内容上遇到不同程度的问题. 懂得ASP/ASP.NET编程  了解ASP/ASP.NET的Session模型  了解ASP.NET Web应用程序模型  了解ASP.NET Web应用程序配置文件Web.config的作用.意义及使用方法  了解Internet Information Services(以下简称IIS)的基本使用方法  了解如何在Microsoft S

ASP.NET Session丢失问题原因及解决方案

正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: <sessionState mode='InProc' stateConnectionString='tcpip=127.0.0.1:424

ASP.NET Session的七点认识

ASP.NET Session的使用当中我们会遇到很多的问题,那么这里我们来谈下经常出现的一些常用ASP.NET Session的理解: ASP.NET Session的七点认识之一 对于值类型的变量,Session中保存的是值类型的拷贝 Session["__test0"] = 1;  int i = (int)Session["__test0"]+1;  int j = (int)Session["__test0"]; 结果i=2,j=1 A

ASP.NET Session丢失问题原因及解决方案[转]

不得不老调重弹 正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: < sessionState mode='InProc' stateConnectionString='tcpip=127.

浅析:微信公众平台账户建立流程

中介交易 SEO诊断 淘宝客 云主机 技术大厅 微信是腾讯公司于11年推出的一款手机聊天软件,由于那时候的微信功能比较简单,人们只是简单的用于发送语音短信.视频.图片和文字等.后来12年腾讯公司在微信的基础上新增了公众号和服务号等功能模块后,微信纷纷成为了企业和人们进行网络营销推广方式之一.这时个人和企业都可以打造一个微信的公众号,通过平台认证,实现二维码订阅.消息推送.品牌传播等.那么微信平台账户是如何建立的呢?还不了解的朋友们可以跟随南宁市爱问站长来了解一下. 一.登录微信公众平台网页,注册