在浏览器中加载虚拟目录名时,AcquireRequestState中的Session为空,但加载Default.aspx时,Session不为空

2024-06-26

我有一个 ASP.NET 4.0 WebForms 应用程序。我需要访问HttpContext.Current.Session并在中设置一个值AcquireRequestStateGlobal.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”位于列表顶部,例如

  1. 默认.aspx
  2. 默认.asp
  3. 默认.htm
  4. ...

我仍然遇到同样的问题。

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 次:

  1. 会话为空
  2. 会话为空
  3. 会话不为空
  4. 会话为空

每次继续单步执行代码时,仅当它开始执行时Default.aspx及其代码隐藏我是否有可用的会话。我实际上在 Firefox 中打开了网页并监视网络请求。第一个请求是为了http://localhost/Foo/.

接下来我设置一个断点Application_BeginRequest以及并得到以下事件:

  1. 开始请求
  2. 获取请求状态
  3. 开始请求
  4. 获取请求状态
  5. 开始请求
  6. AcquireRequestState(会话不为空)
  7. 执行Default.aspx(/Foo向浏览器返回响应)
  8. 开始请求
  9. 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正在等待响应。


I found 讨论 http://forums.asp.net/t/1868629.aspx关于通过显式 URL 提供页面和提供默认文档之间的差异。

通过 MVC 和 WebAPI,引入了新的 HttpModule:无扩展 URL 处理程序。我相信您的事件多次触发(并且只有一次会话可用)可能是由该模块或 ASP.NET 的其他(重新)路由逻辑引起的,这些逻辑实际上重定向 ASP.NET 来处理Default.aspx.

此外,正如您自己提到的,静态文件请求可以触发这些事件。

最重要的是,您不应该依赖可用的会话每次您的活动已被解雇。但可以安全地假设您可以访问会话至少一次提供 ASP.NET 页面时。因此,您的代码应该如下所示:

void Application_AcquireRequestState(object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null)
    {
        HttpContext.Current.Session["key"] = "value";
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在浏览器中加载虚拟目录名时,AcquireRequestState中的Session为空,但加载Default.aspx时,Session不为空 的相关文章

  • 如何将 CroppedBitmap 转换为 BitmapImage

    我正在尝试将 CroppedBitmap 转换为 BitmapImage 编辑 不使用内存流 我尝试过直接转换它 似乎这不是一个选择 这应该没那么难 我正在尝试剪切 BitmapImage 的一部分 并创建一个仅包含新裁剪的 Bitmap
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 指向指针的指针和指向二维数组的指针之间的区别

    如果我有一个二维数组 B 定义为 int B 2 3 1 3 5 2 4 6 Is int p B与 一样int p 3 B int f B printf d f 1 gives 5作为输出 同时printf d f 给出 1 作为答案 为
  • 多态性中基类缺少虚拟析构函数 = 资源泄漏?

    我们知道 如果要多态地使用基类 则需要将基类的析构函数指定为 virtual 否则程序中可能会出现资源泄漏 因为只会调用基类析构函数 而不会调用派生对象析构函数 我们还知道构造函数 析构函数纯粹是初始化 未初始化构造 而operator n
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

    我对 Lambda 表达式的了解有点不稳定 虽然我可以编写使用 Lambda 表达式 又名 LINQ 的代码 但我正在尝试编写自己的方法 该方法采用一些 Lambda 表达式类型的参数 背景 我正在尝试编写一个方法 该方法从任何其他对象类型
  • Linux C++ 调试器

    我正在寻找完美的 Linux C 调试器 我不期望成功 但搜索应该提供丰富的信息 我是一个非常有能力的 gdb 用户 但 STL 和 Boost 很容易压垮我的调试技能 并不是说我无法深入了解数据结构的内部结构 而是它需要很长时间 我通常会
  • 解析通过asp:FileUpload上传的XML文件

    我有一个场景 用户将上传 XML 文件 我想将该文件添加到数据库中的表中 不过 困难的部分是我需要解析文件 然后将一些信息添加到一些不同的表中 显示如何获取 XML 文件的每个示例都使用 URI 来获取文件 但是如何直接从数据库获取文件 或
  • UWP - 绑定枚举差异

    我遇到了一个非常有趣的问题 假设 UWP 应用中有以下 XAML 页面内容
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • 内存不足异常

    我正在使用 C 和 asp net 开发一个网络应用程序 我一直收到内存不足的异常 该应用程序的作用是从数据源读取一堆记录 产品 可能是数百 数千 通过向导中的设置处理这些记录 然后使用处理的产品信息更新不同的数据源 虽然有多个 DB 类
  • 实体框架中的导航属性是什么

    我是实体框架的新手 当Visual Studio创建模型图时我们主要可以看到Entities Propertie和Navigation Properties这两个东西 那么这些Navigation Properties是什么 如何使用它们
  • 链接错误:xxx 已在 *****.LIB 中定义:: 究竟出了什么问题?

    Problem 我正在尝试使用一个名为DCMTK http dicom offis de dcmtk它使用了一些其他外部库 zlib libtiff libpng libxml2 libiconv 我已经从同一网站下载了这些外部库 LIB
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 预览MouseMove 与 MouseMove

    我有相当多的 XAML 经验 但最近我注意到我的大多数同事都使用预览鼠标移动代替鼠标移动事件 我一直用鼠标移动它对我很有帮助 但我忍不住问我什么时候应该使用预览鼠标移动什么时候鼠标移动 有什么区别 各自有什么优点和缺点等等 PreviewM
  • 如何在网页上显示进度条直到网页完全加载?

    我想在网页中显示进度条 加载弹出窗口 直到页面完全加载 我的网页很重 因为它包含一个 HTML 编辑器 这是一个基于 jQuery 的 HTML 编辑器 需要很多时间才能完全加载 在加载时 我希望在页面上显示一个进度条 该进度条将在整个页面
  • RC4 实现与 openssl 输出不匹配

    我的目标是在 C C 中实现 RC4 流密码 并确保它产生与使用时相同的输出openssl命令 按照伪代码维基百科 https en wikipedia org wiki RC4 该实现似乎有效 因为它可以加密和解密内容 但是 加密的输出与
  • Unity 错误“内部构建系统错误。后端退出,代码为 -1073740791。”摧毁/杀死了我的项目

    好吧 我可能在这里夸大了 但这是真的 当我开始打开它时 该项目由于错误 内部构建系统错误 后端退出 代码为 1073740791 而被破坏 应用程序 这个项目已经在Google Play上发布了 也许和设置有关 有人可以帮忙吗 完整错误 I
  • 有关 Endian 性和 .Net 的详细信息?

    我有几个关于字节顺序的问题 这些问题足够相关 我保证将它们作为一个问题提出 1 字节顺序是由 Net还是由硬件决定的 2 如果是由硬件决定的 我怎样才能在C 中找出硬件的字节序 3 字节序是否影响二进制交互 例如 OR AND OR 或移位

随机推荐