在 ASP.NET 开发服务器上调试 HttpModule

13

我想在我的asp.net应用程序(版本3.5,Visual Studio 2008)中集成一些http模块,但我不确定在运行Web应用程序时如何调试或使用这些模块。

我需要将模块源包含在解决方案中还是只需将DLL放入BIN中? 我来自1.1世界,还不习惯使用ASP.NET开发服务器。

5个回答

13

按照以下步骤添加HTTP模块:

  1. 创建一个名为MyModule的新Visual Studio .NET C#类库项目。
  2. 设置对System.Web.dll程序集的引用。
  3. 将以下指令添加到类中:

    using System.Web;                    
    
  4. 重命名类SyncModule.cs,然后更改类定义以反映这一点。

  5. 实现IHttpModule接口。您的类定义应如下所示:

  6. public class SyncModule : IHttpModule                    
    
    决定要订阅哪些事件。下面列出了可以订阅的 HttpApplication 对象的事件:
    • AcquireRequestState:调用此事件以允许模块获取或创建请求的状态(例如,会话)。
    • AuthenticateRequest:当安全模块需要在处理请求之前对用户进行身份验证时,调用此事件。
    • AuthorizeRequest:在认证后,当请求需要被授权时,安全模块将调用此事件。
    • BeginRequest:调用此事件以通知模块新的请求即将开始。
    • Disposed:调用此事件以通知模块应用程序因某种原因即将结束。允许模块执行内部清理。
    • EndRequest:调用此事件以通知模块请求即将结束。
    • Error:调用此事件以通知模块在请求处理期间发生了错误。
    • PostRequestHandlerExecute:调用此事件以通知模块处理程序已完成请求的处理。
    • PreRequestHandlerExecute:调用此事件以通知模块请求的处理程序即将被调用。
    • PreSendRequestContent:调用此事件以通知模块内容即将发送到客户端。
    • PreSendRequestHeaders:调用此事件以通知模块 HTTP 标头即将发送到客户端。
    • ReleaseRequestState:调用此事件以允许模块在处理请求的处理程序完成后释放状态。
    • ResolveRequestCache:在认证后调用此事件。缓存模块使用此事件确定请求是否应由其缓存处理,还是处理程序应该处理请求。
    • UpdateRequestCache:在处理程序响应后调用此事件。缓存模块应更新其缓存以反映响应。
  7. 按以下方式实现 IHttpModule 接口的 Init 和 Dispose 方法:

    public void Init(HttpApplication app)
    {
       app.BeginRequest += new EventHandler(OnBeginRequest);
    }
    public void Dispose(){ }
    
    创建事件的委托方法如下所示:
  8. public delegate void MyEventHandler(Object s, EventArgs e);    
    
  9. 定义一个私有的本地变量,类型为MyEventHandler,用于保存对事件的引用:

  10. private MyEventHandler _eventHandler = null;                    
    
  11. 创建一个事件,将代理与Global.asax文件中继承自HttpApplication对象的方法连接起来:

  12. public event MyEventHandler MyEvent
    {
       add { _eventHandler += value; }
       remove { _eventHandler -= value; }
    }
    
  13. 创建OnBeginRequest方法,将其挂钩到HttpApplicationBeginRequest事件:

  14. public void OnBeginRequest(Object s, EventArgs e)
    {
       HttpApplication app = s as HttpApplication;
       app.Context.Response.Write("Hello from OnBeginRequest in custom module.<br>");
       if(_eventHandler!=null)
          _eventHandler(this, null);
    }        
    
  15. 编译项目

来源:http://support.microsoft.com/kb/307996

将HTTP模块添加到您的web.config文件中,示例如下:

<system.web>
    <httpModules>
       <add name="CustomHttpModule" type="MyCustomHttpModule"/>
    </httpModules>
</system.web>

我该如何在ASP.NET开发环境中使用这个模块?我只需将DLL添加到我的\bin文件夹中,然后在调试时启动的开发Web服务器上运行吗? - Caveatrob
要使用一个 HTTP 模块,你需要在你的 web.config 中定义它。 - Chris Ballance
在我的原始回答中添加了如何将此模块添加到您的web.config的示例。希望这可以帮助您! - Chris Ballance

12

在HttpModule中断点无法命中的常见原因有两种:

断点位于模块构造期间调用的代码中。

这一点总是让我困惑。如果您想要调试模块的构造过程,则应手动附加调试器。 在Windows 7上执行以下操作(Vista上类似):

  1. 调试 | 附加进程...
  2. 勾选 显示所有会话中的进程
  3. 选择您的工作进程实例(w3wp.exe
  4. 单击 附加

刷新浏览器,此时您应该能够命中断点。

由于配置问题,模块实际上没有被加载。

如果您可以确定模块代码确实正在执行,则这不是问题所在。但有时,虽然模块在其他机器上正常加载,但在开发环境中可能由于您拥有不同版本的IIS并且缺少必要的配置而无法加载。

如果是这种情况,请确保将模块正确连接到所有需要的IIS版本。

对于IIS 5.1和IIS 6...

<system.web>
  <httpModules>
    <add name="CustomHttpModule" type="MyCustomHttpModule"/>
  </httpModules>
</system.web>

...并且适用于IIS 7+版本

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="CustomHttpModule" type="MyCustomHttpModule"/>
  </modules>
</system.webServer>

1
我曾经遇到过同样的问题,我的Web配置是为IIS 6设置的,但应该是7。我注意到我不需要“runAllManagedModulesForAllRequests”属性。+1感谢。 - Dai Bok
1
如果您正在使用与Visual Studio集成的开发服务器(即IIS Express),则应将调试器附加到iisexpress.exe而不是w3wp.exe。 - pholpar
如果您想使用IIS调试模块的构造函数或其Init方法,那么在任务管理器或Visual Studio的进程列表中看到该进程时,该代码通常已被调用。在我的情况下(Windows Server 2019 + VS2019),似乎唯一有效的方法是Debugger.Launch()在此处查看详细信息。 不要忘记在投入生产之前从代码中删除该行,或者使用条件仅在调试版本中启用它! - pholpar

5
请注意,这似乎不能直接使用。确保不仅包含新模块的类名,而且要明确定义其命名空间(为了完整起见)和程序集。如果未能这样做,很有可能会导致IIS抱怨无法加载您刚编写的新HTTP模块。
以下是一个例子。
不要这样写:
<add name="CustomHttpModule" type="MyCustomHttpModule"/>

使用:

<add name="CustomHttpModule" type="MyCustomRootNamespace.MyCustomHttpModule, MyCustomAssembly"/>

如果做不到这一点,您的项目可能无法加载。

您可能会收到特定的错误信息,这取决于您定义模块的明确程度。如果您省略了命名空间,您将看到:

Could not load type 'MyCustomHttpModule'.

去掉命名空间并包含程序集,你会看到如下结果:

Could not load type 'MyCustomHttpModule' from assembly 'MyCustomAssembly'. 

如果你看到的是另一条错误信息,那么你遇到的问题与本文所讨论的不同。

3
你可以写下以下代码:

System.Diagnostics.Debugger.Break(); // 明确调用断点以进行调试

在HttpModule构造期间明确调用断点。

它会要求附加进程(例如w3wp.exe),然后调试点将被触发。

谢谢


0

您可能还想确保使用的是 Web 应用程序项目,这是您在 VS2003 中使用的内容,而不是 Web 站点“项目”,因为它们不是项目。


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