Publication de formulaires sur un HttpHandler 404 + dans IIS7: pourquoi toutes les données POST ont-elles disparu?

StackOverflow https://stackoverflow.com/questions/102846

  •  01-07-2019
  •  | 
  •  

Question

OK, cela peut paraître un peu déroutant et compliqué, alors supportez-moi.

Nous avons écrit un cadre qui nous permet de définir des URL conviviales. Si vous naviguez sur une URL arbitraire, IIS tente d'afficher une erreur 404 (ou, dans certains cas, 403; 14 ou 405). Toutefois, IIS est configuré pour que tout ce qui est dirigé vers ces erreurs spécifiques soit envoyé à un fichier .aspx. Cela nous permet d'implémenter un HttpHandler pour gérer la requête et faire des choses, ce qui implique de trouver le modèle associé puis d'exécuter tout ce qui lui est associé.

Maintenant, tout cela fonctionne dans IIS 5 et 6 et, dans une certaine mesure, dans IIS7 - mais pour une capture, ce qui se produit lorsque vous postez un formulaire.

Vous voyez, lorsque vous publiez un formulaire sur une URL inexistante, IIS indique "ah, mais cette URL n'existe pas". et jette une méthode 405 "Méthode non autorisée" Erreur. Puisque nous disons à IIS de rediriger ces erreurs vers notre page .aspx et que nous le gérons donc avec notre HttpHandler, ce n'est normalement pas un problème. Mais depuis IIS7, toutes les informations POST ont disparu après avoir été redirigées vers le 405. Vous ne pouvez donc plus faire les choses les plus insignifiantes impliquant des formulaires.

Pour résoudre ce problème, nous avons essayé d’utiliser un module HttpModule, qui conserve les données POST mais ne semble pas disposer d’une session initialisée au bon moment (lorsque cela est nécessaire). Nous avons également essayé d'utiliser un HttpModule pour toutes les demandes, pas seulement les demandes manquantes 404/403; 14/405, mais cela signifie que des éléments tels que des images, des CSS, des js, etc. sont gérés par du code .NET, ce qui est terriblement inefficace.

Ce qui m'amène à la question actuelle: est-ce que quelqu'un a déjà rencontré ce problème et est-ce que quelqu'un a des conseils ou sait quoi faire pour que les choses fonctionnent à nouveau? Jusqu'à présent, quelqu'un a suggéré d'utiliser le module de réécriture d'URL de Microsoft . Cela aiderait-il à résoudre notre problème?

Merci.

Était-ce utile?

La solution

Microsoft a publié un correctif pour cela:

http://support.microsoft.com/default.aspx/kb/956578

Autres conseils

Etant donné qu'IIS7 utilise .net de haut en bas, l'utilisation d'un HttpModule ne serait pas gênante en performances. En fait, il existe plusieurs HttpModules gérés qui sont toujours utilisés pour chaque requête. Lorsque l'événement BeginRequest est déclenché, le SessionStateModule n'a peut-être pas été ajouté à la collection Modules. Par conséquent, si vous essayez de gérer la demande au cours de cet événement, aucune information sur l'état de la session ne sera disponible. La définition de la propriété HttpContext.Handler initialisera l'état de la session si le gestionnaire demandé en a besoin. Vous pouvez donc définir le gestionnaire sur votre page 404 élégante qui implémente IRequiresSessionState. Le code ci-dessous devrait faire l'affaire, mais vous devrez peut-être écrire une implémentation différente pour la méthode IsMissing ():

using System.Web;
using System.Web.UI;

class Smart404Module : IHttpModule
{
    public void Dispose() {}

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new System.EventHandler(DoMapping);
    }

    void DoMapping(object sender, System.EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (IsMissing(app.Context))
            app.Context.Handler = PageParser.GetCompiledPageInstance(
                "~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
    }

    bool IsMissing(HttpContext context)
    {
        string path = context.Request.MapPath(context.Request.Url.AbsolutePath);

        if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
            && System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
            return true;
        return false;
    }
}

Modifier: j'ai ajouté une implémentation de IsMissing ()

Remarque: sur IIS7, le module d'état de session ne s'exécute pas globalement par défaut. Deux options sont disponibles: Activer le module d’état de session pour toutes les demandes (voir mon commentaire ci-dessus concernant l’exécution de modules gérés pour tous les types de demandes), ou utiliser la réflexion pour accéder aux membres internes de System.Web.dll.

Le problème dans IIS 7 lié au fait que des variables de publication ne soient pas transmises aux gestionnaires d’erreurs personnalisés est résolu dans le Service Pack 2 pour Vista. Je n'ai pas essayé sur Windows Server, mais je suis sûr que cela sera corrigé là aussi.

Juste une supposition: le gestionnaire spécifié dans% windir% \ system32 \ inetsrv \ config \ applicationhost.config d'IIS7 qui traite votre demande n'autorise pas le verbe POST à ??s'exercer et évalue cette règle avant de déterminer si l'URL n'existe pas.

Oui, je recommanderais certainement la réécriture d'URL (en utilisant l'une ou l'autre des nombreuses alternatives de Microsoft IIS7). Ceci est spécialement conçu pour fournir des URL conviviales, alors que les documents d’erreur constituent une solution ultime en cas d’échec, ce qui a tendance à empêcher les données entrantes de ne pas correspondre à vos attentes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top