我有一个应用程序可以点击BeginRequest
和EndRequest
来设置和拆除NHibernate会话,如下所示:
BeginRequest += delegate
{
CurrentSessionContext.Bind(SessionFactory.OpenSession());
};
EndRequest += delegate
{
var session = CurrentSessionContext.Unbind(SessionFactory);
session.Dispose();
Container.Release(session);
};
在IIS中部署时,此工作正常,直到我选中“要求SSL”框。完成此操作后,我会在NullReferenceException
获得session.Dispose()
。
我还没有对此进行调试,是的,修复是微不足道的,但我只是对“需要SSL”如何影响请求的生命周期感到好奇。在这些情况下,服务器上是否未设置会话?
编辑:为了澄清,我指的是IIS配置中的“需要SSL”选项,而不是控制器的RequireHttps
属性。
答案 0 :(得分:5)
这引起了我的好奇,所以我挖了一下;对不起来了。
我创建了一个简单的项目,它为应用程序对象上的每个生命周期事件连接通知,并在每个生命周期事件上设置断点。
事实证明,当设置“要求SSL”并且您在没有SSL的情况下访问时,大多数事件都被完全跳过。要触发的第一个事件是LogRequest
,然后是PostLogRequest
,EndRequest
,PreSendRequestContent
和PreSendRequestHeaders
(按此顺序)。没有其他事件被解雇。
因此,您的代码崩溃了,因为BeginRequest
事件从未被触发,而EndRequest
委托试图Dispose()
从未创建过的东西。
对我来说有趣的是找出为什么 IIS的行为如此。我怀疑原因是IIS仍然需要记录无效的连接尝试,以及发送内容和标头,即使请求的资源需要SSL。毕竟,有些东西必须产生友好的“禁止”页面。我不知道的是,为什么EndRequest
在没有打扰BeginRequest
的情况下被调用的原因;我猜测有一些依赖它的IIS / ASP清理代码。
此行为取决于应用程序池是以“集成”还是“经典”模式运行。在“经典”模式下,ASP.NET事件全部在“PreRequestHandlerExecute
和PostRequestHandlerExecute
事件之间”触发。你没有说你在运行哪个,但它必须是集成的;否则你已经看到了你期望的行为,即你的代码根本就没有执行过。
有趣的是,如果您在经典模式下尝试订阅LogRequest
,PostLogRequest
或MapRequestHandler
事件,则会收到运行时异常;这些只是在综合管道的背景下“有意义”。
答案 1 :(得分:-1)
这可能对您有所帮助
ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0
ASP.NET Application Life Cycle Overview for IIS 7.0
你可能想要在global.asax中做你正在做的事情。