我有一个 ASP.NET 4.0 WebForms 应用程序。我需要访问HttpContext.Current.Session
并在中设置一个值AcquireRequestState
Global.asax 中的事件(或其之后的事件),我发现了一个奇怪的行为。
假设我在 IIS 中有一个虚拟目录(在我的例子中是版本 7),名为Foo
。在那我有Default.aspx
作为主页。一个样品Global.asax
文件如下:
<%@ Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
当我访问时http://localhost/Foo/Default.aspx
在我的浏览器中,它工作得很好。当我访问时http://localhost/Foo/
我得到一个NullReferenceException
我在其中设置会话的值。唯一的变化是浏览器中的 URL。它们最终会到达同一页面,但框架的行为会有所不同,具体取决于 URL 是否仅包含文件夹名称,或者是否包含 aspx 文件。
检查if (HttpContext.Current.Session != null)
对我来说不是一个选择,因为我需要在会话上设置一个值every请求,这是不可协商的。
IIS 中是否有我丢失的配置设置,或者这是一个错误/被遗忘的功能?
一个答案另一个问题 https://stackoverflow.com/questions/4439737/session-is-null-in-prerequesthandlerexecute暗示 IIS 不会为每种请求加载会话,例如样式表不需要会话。发生这种行为的原因可能是 IIS 无法提前判断该文件夹名称是否会导致执行 aspx 文件,或者是否会传递静态 HTML 文件?
Update:我什至尝试重新排序 IIS 查找的默认文档,以便“default.aspx”位于列表顶部,例如
- 默认.aspx
- 默认.asp
- 默认.htm
- ...
我仍然遇到同样的问题。
Update:
事件处理程序仅被触发一次,因为它会导致NullReferenceException
。我做了一些额外的阅读,我知道 ASP.NET 会为每个请求触发这些事件,甚至对于 CSS 或 JavaScript 文件也是如此。此外,静态文件不会加载会话对象,因为没有访问会话的代码,因此不需要加载该对象。即使如此,第一个请求是网页请求,需要session,而session为null。
@DmytroShevchenko 问道:
首先添加一个守卫检查if (HttpContext.Current.Session != null)
这样就没有NullReferenceException
抛出。然后尝试查看,也许该事件会在会话可用的情况下第二次触发。
修改后的代码:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
我设置了一个断点if
陈述。我看到这个事件触发了 4 次:
- 会话为空
- 会话为空
- 会话不为空
- 会话为空
每次继续单步执行代码时,仅当它开始执行时Default.aspx
及其代码隐藏我是否有可用的会话。我实际上在 Firefox 中打开了网页并监视网络请求。第一个请求是为了http://localhost/Foo/
.
接下来我设置一个断点Application_BeginRequest
以及并得到以下事件:
- 开始请求
- 获取请求状态
- 开始请求
- 获取请求状态
- 开始请求
- AcquireRequestState(会话不为空)
- 执行Default.aspx(/Foo向浏览器返回响应)
- 开始请求
- AcquireRequestState(会话再次为空)
在#9 浏览器中的 AJAX 请求http://localhost:54859/8fad4e71e57a4caebe1c6ed7af6f583a/arterySignalR/poll?transport=longPolling&connectionToken=...&messageId=...&requestUrl=http%3A%2F%2Flocalhost%2FFoo%2F&browserName=Firefox&userAgent=Mozilla%2F5.0+(Windows+NT+6.1%3B+WOW64%3B+rv%3A41.0)+Gecko%2F20100101+Firefox%2F41.0&tid=4&_=1445346977956
正在等待响应。