IIS7 Substitue customErrors lors de la définition de Response.StatusCode?

Avoir un problème étrange ici. Tout le monde sait que si vous utilisez la section customErrors de web.config pour créer une page d’erreur personnalisée, vous devez définir votre Response.StatusCode comme il convient. Par exemple, si je crée une page 404 personnalisée et la nomme 404.aspx, je pourrais mettre dans le contenu afin de lui donner un véritable en-tête de statut 404.

Suivez-moi si loin? Bien. Maintenant, essayez de faire cela sur IIS7. Je ne peux pas le faire fonctionner, point. Si Response.StatusCode est défini dans la page d’erreur personnalisée, IIS7 semble remplacer complètement la page d’erreur personnalisée et affiche sa propre page d’état (si vous en avez configuré une).

Quelqu’un a-t-il déjà vu ce comportement et peut-être aussi savoir comment le contourner? Cela fonctionnait sous IIS6, donc je ne sais pas pourquoi les choses ont changé.

Remarque: Ce n’est pas la même chose que le problème dans ASP.NET Custom 404 Retour 200 OK au lieu de 404 introuvable

La méthode la plus simple pour rendre le comportement cohérent consiste à effacer l’erreur et à utiliser Response.TrySkipIisCustomErrors et à définir true sur true. Cela remplacera la gestion de la page d’erreur globale IIS à partir de votre page ou du gestionnaire d’erreur global dans Application_Error.

 Server.ClearError(); Response.TrySkipIisCustomErrors = true; 

En règle générale, vous devez le faire dans votre gestionnaire Application_Error qui gère toutes les erreurs non détectées par vos gestionnaires d’erreurs d’application.

Des informations plus détaillées peuvent être trouvées dans cet article de blog: http://www.west-wind.com/weblog/posts/745738.aspx

Définissez existingResponse sur PassThrough dans la section system.webServer / httpErrors:

     

La valeur par défaut de la propriété existingResponse est Auto:

Auto indique au module d’erreur personnalisé de faire le bon choix. Le texte d’erreur réel vu par les clients sera affecté en fonction de la valeur de fTrySkipCustomErrors renvoyée dans l’appel IHttpResponse::GetStatus . Lorsque fTrySkipCustomErrors est défini sur true, le module d’erreur personnalisé laisse passer la réponse, mais si elle est définie sur false, le module d’erreurs personnalisées remplace le texte par son propre texte.

Plus d’informations: À quoi s’attendre du module d’erreur personnalisé IIS7

Résolu: Il s’avère que les “Erreurs Détaillées” doivent être activées pour que IIS7 “contienne” toute page d’erreur que vous pourriez avoir. Voir http://forums.iis.net/t/1146653.aspx

Je ne suis pas sûr que ce soit de nature similaire ou non, mais j’ai résolu un problème qui semble similaire en surface et voici comment je l’ai géré.

Tout d’abord, la valeur par défaut de existingResponse (Auto) était la bonne réponse dans mon cas, puisque j’ai un custom 404, 400 et 500 (je pourrais en créer d’autres, mais ces trois suffiront à ce que je fais). Voici les sections pertinentes qui m’ont aidé.

De web.config:

  

Et

       

De là, j’ai ajouté ceci dans Application_Error sur global.asax:

  Response.TrySkipIisCustomErrors = True 

Sur chacune de mes pages d’erreur personnalisées, je devais inclure le code d’état de réponse correct. Dans mon cas, j’utilise un 404 personnalisé pour envoyer des utilisateurs vers différentes sections de mon site. Je ne souhaite donc pas qu’un code de statut 404 soit renvoyé, sauf s’il s’agit d’une page morte.

En tout cas, c’est comme ça que je l’ai fait. J’espère que ça aide quelqu’un.

Ce problème a été un casse-tête majeur. Aucune des suggestions mentionnées précédemment n’a résolu le problème pour moi, alors j’inclus ma solution. Pour mémoire, notre environnement / plateforme utilise:

  • .NET Framework 4
  • MVC 3
  • IIS8 (poste de travail) et IIS7 (serveur Web)

Plus précisément, j’essayais d’obtenir une réponse HTTP 404 qui redirectait l’utilisateur vers notre page 404 personnalisée (via les parameters Web.config).

Tout d’abord, mon code devait lancer une HttpException . Le fait de NotFoundResult un NotFoundResult partir du contrôleur n’a pas donné les résultats escomptés.

 throw new HttpException(404, "There is no class with that subject"); 

Ensuite, j’ai dû configurer les nœuds customErrors et httpError dans le httpError Web.config.

    

     

Notez que j’ai laissé la réponse existingResponse sous la forme Auto , ce qui est différent de la solution @sefl fournie.

Les parameters customErrors semblaient nécessaires pour gérer mon HttpException lancée explicitement, tandis que le nœud httpErrors traitait les URL qui ne correspondaient pas aux modèles de route spécifiés dans Globals.asax.cs.

PS Avec ces parameters, je n’ai pas eu besoin de définir Response.TrySkipIisCustomErrors

Par défaut, IIS 7 utilise des messages d’erreur personnalisés détaillés. Je suppose donc que Response.StatusCode sera égal à 404.XX plutôt qu’à 404.

Vous pouvez configurer IIS7 pour utiliser les codes de message d’erreur les plus simples ou modifier votre code pour gérer les messages d’erreur plus détaillés qu’offre IIS7.

Plus d’infos disponibles ici: http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx

Une enquête plus approfondie a révélé que je n’avais pas bien compris – les messages détaillés ne sont pas par défaut, mais ils ont peut-être été activés sur votre boîte si vous voyez les différents messages d’erreur que vous avez mentionnés.

TrySkipIisCustomErrors n’est qu’une partie d’un puzzle. Si vous utilisez des pages d’erreur personnalisées mais que vous souhaitez également fournir un contenu RESTful basé sur des états 4xx, vous rencontrez un problème. Définir httpErrors.existingResponse de web.config à “Auto” ne fonctionne pas, car .net semble toujours fournir du contenu de page à IIS, par conséquent, l’utilisation de “Auto” fait que toutes les pages d’erreur personnalisées ne sont pas utilisées. Utiliser “Remplacer” ne fonctionnera pas non plus, car la réponse contiendra votre code de statut http, mais son contenu sera vide ou rempli avec une page d’erreur personnalisée. Et le “PassThrough” désactive le CEP, donc il ne peut pas être utilisé.

Donc, si vous voulez contourner le protocole CEP dans certains cas (en contournant le fait de renvoyer le statut 4xx avec du contenu), vous aurez besoin d’une étape supplémentaire: nettoyez l’erreur:

 void Application_Error(object sender, EventArgs e) { var httpException = Context.Server.GetLastError() as HttpException; var statusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError; Context.Server.ClearError(); Context.Response.StatusCode = statusCode; } 

Donc, si vous voulez utiliser la réponse REST (400 – Bad Request) et lui envoyer du contenu, vous devrez simplement définir TrySkipIisCustomErrors quelque part dans l’action et définir existingResponse sur “Auto” dans la section httpErrors du fichier web.config. À présent:

  • lorsqu’il n’y a pas d’erreur (l’action renvoie 4xx ou 5xx) et qu’un contenu est renvoyé, le CEP n’est pas utilisé et le contenu est transmis au client;
  • en cas d’erreur (une exception est levée), le contenu renvoyé par les gestionnaires d’erreurs est supprimé, le CEP est donc utilisé.

Si vous souhaitez renvoyer un statut avec un contenu vide de votre action, il sera traité comme une réponse vide et le CEP sera affiché. Il est donc possible d’améliorer ce code.