2010-03-04 4 views
12

J'ai créé un module http personnalisé et je souhaite ajouter ce module à la configuration web. L'application Web est un projet qui contient plusieurs "sous-applications". Une sous-application est juste un dossier, et dans ce dossier il a son propre web.config. Je fais cela pour que chaque application ait ses propres contenus, feuilles de style, config etc.Asp.net HttpModule au niveau du répertoire web.config

Maintenant j'ai créé un module http personnalisé. Lorsque vous ajoutez ceci à la racine web.config, le module fonctionne correctement. Lors de l'ajout de la configuration du module http au fichier web.config au niveau du répertoire (par exemple, /Applications/MyApplication/web.config), le module n'est plus initialisé. Même si msdn indique que l'élément de configuration HttpModules fonctionne également au niveau du répertoire. Quelqu'un sait comment résoudre cela?

Répondre

13

Pour faire écho Marvin Smit's comment, il semble que la configuration <modules> sous un <location> dans web.config simplement ne fonctionne pas - tous les modules spécifiés dans ce mode ne sont pas invoqués.

Ce que vous pouvez faire est de spécifier le module au niveau de la racine, et avoir contrôlé par un appSetting, qui peut être hiérarchiquement spécifiée et réécrite selon les besoins:

<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> 

Puis dans le code pour CustomModule :

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

     return appSetting; 
    } 

ASP.NET veillera à ce que la valeur appropriée de UseCustomModule pour notre emplacement actuel est celui que nous lisons.

+1

Je n'aime certainement pas le fait que c'est la réponse, mais merci de confirmer ce que je soupçonne. – EricTheRed

+0

@AakashM: Quelques observations 1) La méthode ModuleEnabled() a besoin d'un appel quelque part, j'ai essayé de l'appeler en Init et de retourner si elle évalue à false, je ne pouvais pas l'obtenir à partir de là 2) Quand l'appel à ModuleEnabled est dans un événement par exemple PreSendRequestHeaders, ça marche. Pour récapituler, Module est initialisé une fois et ensuite pour chaque invocation, le drapeau est vérifié. SVP corrigez-moi si vous voyez une divergence. – dotnetguy

1

Dans IIS sous votre application racine, sélectionnez votre dossier qui possède web.cofig propre avec HttpModules défini, cliquez droit et sélectionnez la propriété, sur l'onglet Répertoire cliquez sur le bouton Créer.

Il va créer une sous-application et maintenant HttpModules devrait fonctionner.

+2

Ce n'est pas vraiment une solution TBH. Cela modifie l'emplacement racine de l'application. Par conséquent, vous avez besoin d'un nouveau répertoire bin dans le sous-niveau et avez tous les éléments précédemment configurés dans la nouvelle corbeille s'ils ne sont pas GAC'd. Il modifie efficacement votre modèle d'exécution. Je pense que c'est un problème (bug) de ne pas avoir une structure de dossier physcial mais d'avoir des répertoires virtuels pointant vers différents emplacements sur le disque dur qui ne sont pas liés aux ancêtres/descendants! Semble ASP.net n'est pas/en lisant partiellement le web.config si son d'un v-dir où le dossier n'est pas un descendant du dossier de site Web d'application. –

+5

Juste suivi de la recherche. C'est par conception. Les modules et les gestionnaires sont configurés au niveau de l'application. (Dox état n'importe quel niveau, mais c'est une contrainte de by-design by by-design du modèle de service) –

1

Ne serait-il pas possible de créer une section de configuration personnalisée qui répertorie les répertoires que vous souhaitez inclure ou exclure du comportement de votre module? Votre module pourrait alors inspecter cela pour voir s'il devrait faire son travail basé sur l'URL de demande.

Je sais que ce n'est pas tout à fait ce que vous demandez, mais vous donnerait certainement le comportement dont vous avez besoin.

0

base HttpModule pour ce cas pourrait être la suivante:

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() 
    { 
    } 
} 
Questions connexes