【问题标题】:Asp.net HttpModule in directory level web.config目录级别 web.config 中的 Asp.net HttpModule
【发布时间】:2023-03-06 17:47:01
【问题描述】:

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

现在我创建了一个自定义 http 模块。将此添加到根 web.config 时,该模块工作正常。将 http 模块配置添加到目录级 web.config(例如 /Applications/MyApplication/web.config)时,模块不再初始化。即使 msdn 声明 HttpModules 配置元素也在目录级别工作。有谁知道如何解决这个问题?

【问题讨论】:

    标签: .net asp.net


    【解决方案1】:

    为了回显Marvin Smit's comment,似乎在web.config 中的<location> 下配置<modules> 只是不起作用 - 不会调用以这种方式指定的任何模块。

    可以做的是在根级别指定模块,并由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 的正确值是我们当前位置的正确值。

    【讨论】:

    • 我当然不喜欢这是答案,但感谢您确认我的怀疑。
    • @AakashM : 一些观察 1) ModuleEnabled() 方法需要在某个地方调用,我尝试在 Init 中调用它并返回如果它评估为假,则无法从那里开始工作 2) 当对 ModuleEnabled 的调用是在一个事件中,例如PreSendRequestHeaders,它有效。总而言之,Module 被初始化一次,然后每次调用都会检查标志。如果您发现任何差异,请纠正我。
    【解决方案2】:

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

    它将创建子应用程序,现在 HttpModules 应该可以工作了。

    【讨论】:

    • 这并不是真正的解决方案。它更改应用程序的根位置。因此,您需要在子级别中有一个新的 bin 目录,并且如果它们不是 GAC 的,则将所有以前配置的项目都放在新的 bin 中。它有效地改变了你的运行时模型。我认为这是一个问题(错误),没有物理文件夹结构,但虚拟目录指向硬盘驱动器上与祖先/后代无关的不同位置!似乎 ASP.net 没有/部分读取 web.config,如果它来自一个文件夹不是应用程序网站文件夹的后代的 v-dir。
    • 刚刚跟进研究。它的设计。模块和处理程序是在应用程序级别配置的。 (Dox 声明任何级别,但这是由服务模型的设计约束记录的)
    【解决方案3】:

    难道不能创建一个自定义配置部分来列出您想要包含或排除您的模块行为的目录吗?然后,您的模块可以检查它是否应该根据请求 URL 完成工作。

    我知道这不是你要问的,但肯定会给你你需要的行为。

    【讨论】:

      【解决方案4】:

      此案例的基本 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()
          {
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-01-22
        • 1970-01-01
        • 1970-01-01
        • 2016-12-17
        • 2012-07-23
        • 2015-11-23
        • 2011-06-05
        • 1970-01-01
        • 2010-12-08
        相关资源
        最近更新 更多