在一个 HttpModule 中挂钩 Application_Start。

10

我正在实现一个简单的HttpModule,想要在Web应用程序启动时运行一些代码。但我惊讶地发现,我通常从Global.asax使用的Application_Start事件在HttpModule中不可用。这是正确的吗,还是我漏掉了什么?

如何从HttpModule钩入Application_Start事件?

更新:
我已经通过使用Init事件找到了一个简单的解决方案,但它仍然让我感到有点奇怪。

6个回答

29

您可以使用HttpModule来处理应用程序启动事件

与其他人只写/相信他们读到的不同,我已经做了自己的部分,并发现可以使用HTTP模块来处理应用程序启动。这实际上是一种有点 hack 的方法,但可靠地工作。这绝对不是一个应该避免的东西,因为我在微软模块中也看到过(即 Sharepoint 2010 SPRequestModule)。我的这篇博客文章(编写一个能够处理 Application_Start 事件的自定义 IHttpModule)将为您提供关于此的所有信息。我已经亲自尝试过,它确实有效。但是,当使用常见资源时,您必须要小心,因为您的应用程序可能会开始表现奇怪。为避免这种情况,我建议您阅读我另一篇博客文章,其中解释了为什么会出现这种情况以及如何避免。

如果您还想使它线程安全,那么您还可以锁定执行,然后将模块标记为应用程序已启动。这是最安全的方法。

private static bool isStarted = false;
private static object moduleStart = new Object();
...
if (!isStarted)
{
    lock(moduleStart)
    {
        if (!isStarted)
        {
            // handle aplication start
            ...
            isStarted = true;
        }
    }
}
我已经创建了一个可以连接到像Sharepoint 2010这样的现有应用程序的库。 我现在不想改变Sharepoint的Global.asax。使用博客文章中解释的技术,我成功地将其连接起来了。很容易。
我猜这正是你一直在寻找的。通过在web.config中添加模块来钩取任意应用程序的启动事件。就这么做,它会工作的。

@downvoter:请问您为什么对这个答案进行了负评?也许我们可以讨论一下您不满意的细节,我的回答可能会得到改进? - Robert Koritnik
1
这实际上并没有处理Application_Start,它只是模拟它。对于我能想到的大多数情况,这肯定是有效的。 - Erik Philips

1

在 HttpModule 中无法附加到 Application_Start 事件。这里是可用事件列表


嗯,这正是我担心的。我是否有其他选项来创建可重用库,只需添加dll和一些web.config更改即可在现有Web应用程序上部署? - Jakob Gade
这个可重用库应该做什么? - Darin Dimitrov
它发送一个通知,表示Web应用程序已启动。 - Jakob Gade

1

我同意Darin的观点。

原因是应用程序需要被加载才能加载模块,那么在应用程序准备开始加载模块之前如何执行模块内的代码呢?

你想做什么? 也许值得评估一下你的解决方案的想法 :)

希望这可以帮到你 :)


1
难道不应该至少有一个“我准备好了”的事件,当所有模块都已加载并且应用程序正在运行时触发吗?我试图向远程服务器发送通知,以指示站点已经(重新)加载。 - Jakob Gade

1
我对这个帖子和网站如何开始产生了兴趣,是在修复一个旧的ASP.NET网站中的一个错误时。所以我做了一个演示来看看它是如何工作的。似乎顺序是从web.config文件中确定的。你可以在这里看到:https://github.com/jradxl/MVC-Website-Without-Global.asax.cs 它实现了Robert Koritnik的解决方案 - 谢谢。

0
事实上,每个应用程序池重启之前,特定的http模块只会存在一个实例。当然,对于你的Web应用程序中的每个w3wp.exe工作进程也是如此。
换句话说,使用init方法或构造函数进行初始化、预加载数据等,并且不要使用静态字段,除非你需要在事件触发后对你的模块订阅的数据进行锁定并更改你的模块控制或包含的属性。无论如何,init方法都会在应用程序启动时被调用。

0
一个模块的Init()方法加锁后,如何知道它会不会被首先调用?其他模块难道不可能先被实例化吗? 这不就是Global.asax的Application_Start事件的区别吗——它是通过设计保证最先被调用的吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接