ASP.NET 中的 HttpModule 在目录级别的 Web.config 中

12

我创建了一个自定义的http模块,并想要将其添加到web config中。这个web应用程序是一个包含多个"子应用程序"的项目。一个子应用程序只是一个文件夹,它有自己的web.config。我这样做是为了使每个应用程序都有自己的应用程序相关内容、样式表、配置等。

现在我创建了一个自定义的http模块。将其添加到根web.config时,模块可以正常工作。但是当将http模块配置添加到目录级别的web.config(例如/Applications/MyApplication/web.config)时,该模块就无法初始化了。尽管MSDN说明HttpModules配置元素也适用于目录级别。有人知道如何解决这个问题吗?

4个回答

15
为了响应Marvin Smit的评论,配置<modules>web.config中的<location>似乎根本不起作用 - 以这种方式指定的任何模块都不会被调用。

您可以做的是在根级别指定模块,并由appSetting控制,可以按需要进行分层指定和覆盖:

<configuration>


  <appSettings>
    <add key="UseCustomModule" value="false"/>
  </appSettings>


  <location path="MyFolder">
    <appSettings>
      <add key="UseCustomModule" value="true"/>
    </appSettings>
    <system.webServer>
      <modules>
        <!-- CANNOT add module at this level, hence the overridden appSetting -->
      </modules>
    </system.webServer>
  </location>

  <system.webServer>
    <modules>
      <add name="CustomnModule" type="MyApplication.CustomModule" />
    </modules>
  </system.webServer>

</configuration>

然后在CustomModule代码中:

    private static bool ModuleEnabled()
    {
        bool appSetting;
        if (!bool.TryParse(ConfigurationManager.AppSettings["UseCustomModule"], 
                           out appSetting))
            appSetting = false;

        return appSetting;
    }

ASP.NET会确保我们读取的当前位置的UseCustomModule的适当值。


1
我当然不喜欢这就是答案的事实,但感谢您确认了我所怀疑的。 - EricTheRed
@AakashM:一些观察结果 1)ModuleEnabled()方法需要在某处调用,我尝试在Init中调用它并在评估为false时返回,但无法从那里使其工作。2)当在事件(例如PreSendRequestHeaders)中调用ModuleEnabled时,它可以正常工作。总结一下,模块被初始化一次,然后对于每个调用,都会检查标志。如果您发现任何差异,请纠正我。 - Sudhanshu Mishra

1
在IIS中,在根应用程序下选择具有定义了HttpModules的自己web.cofig的文件夹,右键单击并选择属性,在目录选项卡上单击创建按钮。
它将创建子应用程序,现在HttpModules应该工作。

2
这并不是一个真正的解决方案。实际上它改变了应用程序的根位置。因此,你需要在子级中有一个新的bin目录,并将所有以前配置的项目放到新的bin中,如果它们没有被GAC'd。它有效地改变了您的运行时模型。我认为这是一个问题(错误),并没有物理文件夹结构,而是有虚拟目录指向硬盘上不与祖先/后代相关的不同位置!似乎ASP.net在从v-dir读取Web.config时无法完全读取,其中该文件夹不是应用程序网站文件夹的后代。 - Marvin Smit
5
刚刚跟进了这项研究。这是有意而为之的。模块和处理程序是在应用程序级别上进行配置的。(文档中没有说明级别,但这是服务模型的设计限制,尽管未经记录) - Marvin Smit

1

是否可以创建一个自定义配置部分,列出您想要包含或排除模块行为的目录?然后,您的模块可以检查它,以查看是否应基于请求URL执行其工作。

我知道这不完全是您要求的内容,但肯定会给您所需的行为。


0

对于这种情况,基本的HttpModule可以是以下内容:

public abstract class PathBasedHttpModule : IHttpModule
{
    public abstract void Init(HttpApplication context);

    protected EventHandler BuildConditionalEventHandler(Action<object, EventArgs> targetHandler)
    {
        EventHandler action = (sender, args) =>
        {
            var settingsValue = CloudConfigurationManager.GetSetting(ModuleEnabledAppSettings);
            if (!string.IsNullOrEmpty(settingsValue) && bool.Parse(settingsValue))
            {
                targetHandler(sender, args);
            }
        };
        return action;
    }

    protected abstract string ModuleEnabledAppSettings
    {
        get;
    }

    public void Dispose()
    {
    }
}

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