ASP.NET 会话状态是一种允许您存储服务器端、特定于用户的数据的技术。Web 应用程序可以使用这些数据处理来自为其实例化会话状态的用户的请求。会话状态用户由会话 ID 标识。通过使用以下方法之一传送会话 ID:
•
会话 ID 是发送到用户浏览器的 Cookie 的一部分。
•
会话 ID 嵌入在 URL 中。此技术也称为“无 Cookie 会话”。
• | 会话 ID 是发送到用户浏览器的 Cookie 的一部分。 |
• | 会话 ID 嵌入在 URL 中。此技术也称为“无 Cookie 会话”。 |
会话 ID 是一个由 20 个字符组成的字符串表示的 120 位随机数。字符串的格式设置为可以包含在 URL 中并且不必进行 URL 编码。例如,可以在无 Cookie 会话中使用字符串。传送会话 ID 的最常用方法是通过使用 Cookie 来存储会话 ID。
当用户第一次打开 Web 浏览器并转到某个实现 ASP.NET 会话状态的网站时,将向浏览器发送一个名为“ASP.NET_SessionId”并包含由 20 个字符组成的值的 Cookie。
当用户在相同的 DNS 域中浏览时,Web 浏览器将继续向作为源的域发送此 Cookie。
例如,app1.tailspintoys.com 和 app2.tailspintoys.com 都是 ASP.NET 应用程序。如果用户先后转到 app1.tailspintoys.com 和 app2.tailspintoys.com,则这两个应用程序将会使用相同的 Cookie 和相同的会话 ID,以跟踪用户在每个应用程序内的会话状态。应用程序之间不会共享相同的会话状态。应用程序之间只共享会话 ID。
因此,可以出于多种原因重用会话 ID。例如,如果重用会话 ID,则不必执行下面的操作:
•
当向您提供有效的会话 ID 时,将创建一个新加密的唯一会话 ID。
•
为单个域中的每个 ASP.NET 应用程序创建新的会话 ID。
• | 当向您提供有效的会话 ID 时,将创建一个新加密的唯一会话 ID。 |
• | 为单个域中的每个 ASP.NET 应用程序创建新的会话 ID。 |
当 Web 应用程序要求登录并提供注销页或选项时,建议您在用户注销网站后清除会话状态。若要清除会话状态,请调用“Session.Abandon”方法。使用“Session.Abandon”方法可以刷新会话状态,而无需等到会话状态超时。默认情况下,超时时间为 20 分钟的可调过期。每当用户向网站发出请求并提供会话 ID Cookie 时都会刷新此过期期限。“Abandon”方法在指示应放弃会话状态的会话状态对象中设置一个标志。在页面请求的末尾将检查该标志并进行处理。因此,在调用“Abandon”方法之后,用户可以在页面中使用会话对象。一旦完成页面处理,即会删除会话。
当使用进程内会话状态模式时,这些会话状态对象将存储在 HttpCache 中。当满足下面的条件时,HttpCache 支持回调方法:
•
删除了缓存项。
•
会话状态管理器注册了在删除缓存项时要调用的“Session_OnEnd”事件处理程序。
• | 删除了缓存项。 |
• | 会话状态管理器注册了在删除缓存项时要调用的“Session_OnEnd”事件处理程序。 |
当会话状态管理器删除驻留在缓存中的会话状态对象时,HttpCache 管理器将调用所有已注册的回调。实际上,此行为将引发“Session_OnEnd”事件处理程序。
当您放弃会话时,将不会从用户的浏览器中删除会话 ID Cookie。因此,一旦放弃会话,对同一个应用程序的任何新请求都将使用相同的会话 ID,但具有新的会话状态实例。同时,如果用户在相同的 DNS 域内打开另一个应用程序,则在从一个应用程序调用“Abandon”方法后,用户将不会丢失其会话状态。
有时,您可能不希望重用会话 ID。如果是这样而且您了解不重用会话 ID 的后果,请使用下面的代码示例以放弃会话并清除会话 ID Cookie:
Session.Abandon(); Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
此代码示例从服务器中清除会话状态,并将会话状态 Cookie 设置为空值。空值可以有效地从浏览器中清除 Cookie。 当用户没有从应用程序注销并且发生会话状态超时时,应用程序可能仍将使用同一个会话状态 Cookie(如果没有关闭浏览器)。 此行为将导致用户转到登录页,并且提供用户的会话状态 Cookie。 为了保证在打开登录页 (login.aspx) 时使用新的 ID,应将空 Cookie 发送回客户端。为此,将 Cookie 添加到响应集合中。然后,将响应集合发送回客户端。发送空 Cookie 的最简单方法是通过使用“Response.Redirect”方法。由于 Cookie 集合对于 ASP.NET_SessionId 始终具有一个值,因此您不能仅仅测试此 Cookie 是否存在,这样将会创建一个“Response.Redirect”循环。可以针对重定向到登录页设置查询字符串。
或者,可以使用不同的 Cookie 来通知您是否已经重定向到登录页,如下面的代码示例所示。为了帮助提高安全性,确保没有任何用户尝试通过使用 ASP.NET Cookie 和另一个 Cookie 来打开登录页,下面的代码示例使用“FormsAuthentication”类来对 Cookie 数据进行加密和解密。然后,代码示例设置 5 秒钟的超时时间。
private void Page_Load(object sender, System.EventArgs e)
{
if( !IsPostBack &&
( Request.Cookies["__LOGINCOOKIE__"] == null ||
Request.Cookies["__LOGINCOOKIE__"].Value == "" ) )
{
//At this point, we do not know if the session ID that we have is a new
//session ID or if the session ID was passed by the client.
//Update the session ID.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
//To make sure that the client clears the session ID cookie, respond to the client to tell
//it that we have responded. To do this, set another cookie.
AddRedirCookie();
Response.Redirect( Request.Path );
}
//Make sure that someone is not trying to spoof.
try
{
FormsAuthenticationTicket ticket =
FormsAuthentication.Decrypt( Request.Cookies["__LOGINCOOKIE__"].Value );
if( ticket == null || ticket.Expired == true )
throw new Exception();
RemoveRedirCookie();
}
catch
{
//If someone is trying to spoof, do it again.
AddRedirCookie();
Response.Redirect( Request.Path );
}
Response.Write("Session.SessionID="+Session.SessionID+"<br/>");
Response.Write("Cookie ASP.NET_SessionId="+Request.Cookies["ASP.NET_SessionId"].Value+"<br/>");
}
private void RemoveRedirCookie()
{
Response.Cookies.Add(new HttpCookie("__LOGINCOOKIE__", ""));
}
private void AddRedirCookie()
{
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket(1,"Test",DateTime.Now,DateTime.Now.AddSeconds(5), false,"");
string encryptedText = FormsAuthentication.Encrypt( ticket );
Response.Cookies.Add( new HttpCookie( "__LOGINCOOKIE__", encryptedText ) );
}
注意这句话:Session.Abandon(); Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
有人会问Session.Abandon(); 和Session.clear(); 有什么不一样,在这一并说明下吧
主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下)。
当下一个请求到来时将激发Session_Start方法。
而Session.Clear只是清除Session中的所有数据并不会中止该Session,因此也不会调用那些方法。
Session.Abandon()其实就等于将此次连接断开,而clear() 是没有断开
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现