12

我有一个应用程序可以像这样接入BeginRequestEndRequest设置和拆除 NHibernate 会话:

BeginRequest += delegate
{
    CurrentSessionContext.Bind(SessionFactory.OpenSession());
};

EndRequest += delegate
{
    var session = CurrentSessionContext.Unbind(SessionFactory);
    session.Dispose();

    Container.Release(session);
};

这在 IIS 中部署时可以正常工作,直到我选中“需要 SSL”框。一旦我这样做,我会得到一个NullReferenceExceptionat session.Dispose()

我还没有调试过这个,是的,修复很简单,但我只是好奇“需要 SSL”如何影响请求的生命周期。在这些情况下,是否没有在服务器上设置会话?

编辑:为了澄清,我指的是应用程序的 IIS 配置中的“需要 SSL”选项,而不是RequireHttps控制器的属性。

4

2 回答 2

5

这个引起了我的好奇心,所以我深入研究了它;对不起死灵术。

我创建了一个简单的项目,它为应用程序对象上的每个生命周期事件连接通知,并在每个事件上设置断点。

事实证明,当设置了“需要 SSL”并且您在没有 SSL 的情况下访问时,大部分事件都被完全跳过。触发的第一个事件是LogRequest,然后是PostLogRequestEndRequestPreSendRequestContentPreSendRequestHeaders(按此顺序)。不会触发其他事件。

因此,您的代码崩溃了,因为该BeginRequest事件从未被触发,并且EndRequest委托尝试Dispose()了从未创建过的东西。

我感兴趣的是弄清楚为什么IIS 会这样。我怀疑原因是 IIS 仍然需要记录无效的连接尝试,以及发送内容和标头,即使请求的资源需要 SSL。毕竟,有些东西必须生成那个友好的“禁止”页面。我不知道的是EndRequest,当他们不打扰时,为什么会被调用BeginRequest;我猜有一些 IIS/ASP 清理代码依赖于它。

此行为取决于应用程序池是在“集成”模式还是“经典”模式下运行。PreRequestHandlerExecute在“经典”模式下,ASP.NET 事件都在 IIS和事件“之间”触发PostRequestHandlerExecute。你没有说你在运行哪个,但它必须是集成的;否则你会看到你所期望的行为,即你的代码根本不会执行。

有趣的是,如果您在 Classic 模式下尝试订阅LogRequestPostLogRequestMapRequestHandler事件,您会得到运行时异常;这些仅在集成管道的背景下“有意义”。

于 2011-03-13T21:29:36.820 回答
-1

这里有一些可以帮助你的东西

IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述

IIS 7.0 的 ASP.NET 应用程序生命周期概述

您可能想要做您在 global.asax 中所做的事情。

于 2011-02-09T17:28:31.107 回答