Asp.net 在没有GAC的多个子应用程序之间共享HttpModule

Asp.net 在没有GAC的多个子应用程序之间共享HttpModule,asp.net,.net,iis,httpmodule,Asp.net,.net,Iis,Httpmodule,我在IIS中设置了一个网站,在根目录下为许多子应用程序虚拟(大约35个)设置了一个web.config,其中一些使用自己独特的覆盖/配置 我有两个httpmodule,我想同时为所有子应用程序实现。在不使用GAC的情况下,是否有办法在web.config中指定实现,以便这些模块可以应用于所有子应用程序,而无需将模块代码重新编译到每个子应用程序中?我是否可以将HttpModule程序集存储在站点结构中的某个位置,以便所有子应用程序都可以使用它?您可以在dll中添加http模块。将DLL放在应用程序

我在IIS中设置了一个网站,在根目录下为许多子应用程序虚拟(大约35个)设置了一个web.config,其中一些使用自己独特的覆盖/配置


我有两个httpmodule,我想同时为所有子应用程序实现。在不使用GAC的情况下,是否有办法在web.config中指定实现,以便这些模块可以应用于所有子应用程序,而无需将模块代码重新编译到每个子应用程序中?我是否可以将HttpModule程序集存储在站点结构中的某个位置,以便所有子应用程序都可以使用它?

您可以在dll中添加http模块。将DLL放在应用程序的bin文件夹中,并从web.config中引用http模块

    <add name="MyHttpModule" type="MyDll.MyHttpModule, MyDll" /> 

假设在事件发生后将其添加到web配置和bin文件夹的正常操作不适用于您,那么在当前框架中,您有几种可能:

如果您不介意更改web配置,但需要将模块存储在bin之外,则可以使用System.web.PreApplicationStartMethod为AppDomain.AssemblyResolve事件注册处理程序,然后加载事件处理程序并返回类型

如果您不想修改web.config或需要将事件放在堆栈顶部就像打开它并更改机器级别的web配置一样,您可以使用System.web.PreApplicationStartMethod来获取代码,以便在启动时运行,只需将其放在bin目录中,然后使用MVC Razor库中的Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule。这样做的结果与机器模块列表中的最后一个模块大致相同

如果您不想修改web配置,并且需要在事件堆栈中的较早位置,那么您需要做一些事情来重新排序事件处理程序。我需要这样做一次,以尝试和调试吞咽错误的东西。在reflector中进行了一些探索,我提出了这个函数来获取现有的事件处理程序

Dim t As Type = target.[GetType]()

Public Function GetEventSubscribers(ByVal target As Object, ByVal eventName As String) As [Delegate]()
    Dim w = CType(t.GetField("_events", BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.NonPublic).GetValue(target), System.ComponentModel.EventHandlerList)
    Dim k = t.GetFields(BindingFlags.[Static] Or BindingFlags.Instance Or BindingFlags.NonPublic).Where(Function(x) x.Name.StartsWith("Event" & eventName)).Select(Function(x) x.GetValue(target)).ToList()
    Dim d() As [Delegate] = k.SelectMany(Function(x)
        If w(x) Is Nothing Then
            New [Delegate]() {}
        Else
            Return w(x).GetInvocationList()
        End If
    End Function).ToArray
    Return d
End Function
如果使用EventName将HttpApplication实例传递给它,则会获得所有已注册的处理程序委托,这将允许您对每个委托调用RemoveEventHandler()


如果对错误事件执行此操作,则添加自己的处理程序,然后按照正确的顺序重新添加预先存在的委托,然后首先触发处理程序,在任何其他处理程序有机会破坏偶数状态之前,只要您自己不更改事件状态,应用程序的其余部分似乎都不明智。

可以在根web.config(
system.webServer/modules
部分)中注册http模块。模块必须具有强名称(必须签名):


这是一个非常有用的提示。谢谢
<add name="MyModule" preCondition="managedHandler" type="MyModule.Namespace, MyModuleAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bfd166351ed997df" />
   <runtime>
        <assemblyBinding appliesTo="v2.0.50727" xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="MyModuleAssembly" publicKeyToken="bfd166351ed997df"/>
                <codeBase version="1.0.0.0"
                          href="file://c:/SharedLibs/MyModuleAssembly.dll" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>