Utilisation de modules et de gestionnaires HTTP pour créer des composants ASP.NET enfichables

Scott Mitchell, 4GuysFromRolla.com
Atif Aziz, Skybow AG

Septembre 2004

Résumé : Dans cet article, Scott Mitchell et Atif Aziz expliquent comment utiliser des modules et des gestionnaires HTTP pour ajouter une fonctionnalité d'enregistrement des erreurs dans vos applications ASP.NET. Cet article contient des liens vers des pages en anglais. (22 pages imprimées)

Téléchargez le fichier exemple MSDNElmah.msi.

Sommaire

Introduction
ELMAH : Modules et gestionnaires d'enregistrement des erreurs
Brève présentation des gestionnaires et modules HTTP
Examen de l'architecture ELMAH
Ajout de ELMAH dans une application Web ASP.NET
Conclusion
Références
Bibliographie

Introduction

Avez-vous déjà travaillé sur une application ASP.NET et conçu une fonctionnalité ou un ensemble de fonctions utiles que vous auriez aimé pouvoir réutiliser facilement dans une autre application ASP.NET ? ASP.NET offre plusieurs outils permettant de modulariser des fonctionnalités, quel qu'en soit le type. Les deux outils les plus courants qui permettent une réutilisation dans ASP.NET sont :

  • les contrôles utilisateur et les contrôles serveur personnalisés et compilés pour des fonctionnalités et des éléments d'interface utilisateur,
  • les bibliothèques de classes NET pour un code d'accès aux données et une logique métier.

Deux outils ASP.NET qui facilitent la réutilisation des composants et auxquels on prête généralement peu d'attention sont les gestionnaires et les modules HTTP.

Si les gestionnaires et modules HTTP ne vous sont guère familiers, ne vous inquiétez pas. Nous allons en parler un peu plus loin dans cet article. Pour le moment, contentons-nous de rappeler que les modules HTTP sont des classes qu'il est possible de configurer afin qu'elles s'exécutent en réponse à des événements déclenchés lors d'une demande de ressource ASP.NET. Un gestionnaire HTTP est une classe dont le rôle est de générer une ressource particulière ou un type particulier de ressource. En fait, chaque fois que vous ajoutez une page Web ASP.NET dans votre projet, vous écrivez un gestionnaire HTTP. En effet, lorsque la partie HTML d'une page Web ASP.NET est compilée dynamiquement au moment de l'exécution, elle hérite, directement ou indirectement, de System.Web.UI.Page, ce qui revient en réalité à implémenter un gestionnaire HTTP. Ceci est valable quelle que soit la stratégie adoptée, en ligne ou code-behind.

Comme vous le savez, une application ASP.NET se compose habituellement d'un ensemble de pages Web qui sont appelées lorsqu'elles sont demandées par le navigateur d'un utilisateur. La plus grande partie du code que nous écrivons en tant que développeurs ASP.NET est spécifique à une demande de page Web particulière ; c'est le cas par exemple du code contenu dans la classe code-behind d'une page et permettant d'afficher les résultats de la base de données en fonction d'une requête de recherche. Il arrive pourtant que nous ayons besoin d'écrire du code orthogonal aux pages Web individuelles, c'est-à-dire qui s'applique à toutes les pages d'une application. Imaginons que nous voulions savoir dans quel ordre les utilisateurs se déplacent dans notre site Web. Pour ce faire, chaque page doit enregistrer l'heure de la demande et les informations qui identifient l'utilisateur.

Pour que cet enregistrement soit possible, nous pourrions ajouter un code qui enregistre les données pertinentes d'une base de données dans le gestionnaire d'événement Page_Load pour chaque page Web du site. Toutefois, il s'agit là d'une approche difficile à gérer ou à réutiliser. Chaque fois que nous ajoutons une nouvelle page ASP.NET dans notre site, nous devons être sûr d'avoir inclus le code d'enregistrement approprié. Si nous voulions ajouter une fonctionnalité similaire dans un autre site, nous devrions accéder à chaque page du site et ajouter le code nécessaire. Dans l'idéal, la fonctionnalité d'enregistrement devrait être logiquement et physiquement distincte de la fonctionnalité de chaque page, et son insertion dans un autre site devrait être aussi simple que la copie d'un assembly dans le répertoire /bin du site.

Désormais, grâce aux modules et aux gestionnaires HTTP, la facilité de gestion et de réutilisation est chose possible. Dans cet article, nous allons examiner un ensemble de modules et de gestionnaires HTTP conçus pour rendre la fonction d'enregistrement des erreurs considérablement plus facile à gérer et à réutiliser. Le but de cet article est de montrer comment les gestionnaires et les modules HTTP permettent d'atteindre un haut niveau de modularité, permettant la mise au point, le conditionnement et le déploiement d'ensembles complets de fonctionnalités sous la forme d'une seule unité, indépendante des applications Web. Nous parviendrons à cet objectif en examinant essentiellement une application qui tire parti de la facilité de réutilisation et de la modularité qu'autorisent désormais les gestionnaires et les modules HTTP.

ELMAH : gestionnaires et modules d'enregistrement des erreurs

Les gestionnaires et modules d'enregistrement des erreurs ELMAH (Error Logging Modules And Handlers) que nous allons examiner dans cet article ont été écrits en collaboration avec Atif Aziz (http://www.raboof.com/) ; ils permettent d'ajouter très facilement des fonctions d'enregistrement des erreurs dans une application Web ASP.NET. ELMAH montre comment les modules et gestionnaires HTTP permettent d'obtenir un niveau de modularité exceptionnel pour un code qui est orthogonal à l'application Web (tel qu'une fonction d'enregistrement à l'échelle de l'application). ELMAH est une solution parfaitement enfichable, ce qui signifie qu'il est possible de l'ajouter dynamiquement dans une application Web ASP.NET active, sans devoir procéder à une recompilation ou à un redéploiement.

Même si votre application Web est très bien écrite et testée, les choses peuvent mal tourner à un moment ou à un autre. Ce n'est pas obligatoirement la faute du code que vous avez écrit ; les problèmes peuvent venir d'un serveur de messagerie qui ne répond pas ou d'un échec de cryptographie dû à une corruption des données. Quoi qu'il en soit, lorsqu'une exception se produit, notamment sur un site actif, vous avez tout intérêt à enregistrer les détails qui s'y rapportent pour mieux diagnostiquer le problème. ELMAH offre précisément un mécanisme pour l'enregistrement centralisé des erreurs et leur notification. Lorsque, dans une application ASP.NET, il se produit une exception qui n'est pas interceptée, ELMAH en est averti et il la traite comme indiqué dans le fichier Web.config. Ce traitement peut inclure l'enregistrement des détails de l'exception dans une base de données, l'envoi d'un courrier électronique à l'administrateur, ou les deux.

ELMAH n'est pas conçu pour répondre avec élégance à des exceptions non gérées. Il se contente d'enregistrer les détails les concernant. Une fois que ELMAH a été ajouté dans une application Web ASP.NET, les exceptions non gérées qui surviennent dans cette application sont enregistrées. En apparence, rien ne change pour l'utilisateur lorsqu'une exception non gérée se produit. La page "Server Error" continue de s'afficher ou, si des messages d'erreur personnalisés ont été configurés pour traiter les erreurs HTTP de type 500, celles-ci sont redirigées vers une page avec un message plus explicite. En coulisses toutefois, ELMAH aura détecté l'existence d'une exception non gérée et enregistré les détails correspondants.

ELMAH découvre les exceptions non gérées par le biais de l' événement Error de l'objet HttpApplication. L'événement Error est déclenché lorsqu'une exception non gérée survient pendant le traitement d'une demande, que ce soit à partir d'une bibliothèque de classes .NET ou d'une page Web ASP.NET. N'oubliez pas que bon nombre d'applications ASP.NET mettent incorrectement en œuvre le traitement des pages d'erreur personnalisées en appelant la méthode Server.ClearError(). La suppression de l'erreur empêche le déclenchement de l'événement Error (ainsi que sa signalisation au client), de sorte que ELMAH n'a aucune chance de pouvoir enregistrer l'exception. En d'autres termes, lorsque vous utilisez ClearError() dans une page d'erreur personnalisée, l'utilisateur verra qu'un problème s'est produit, mais pas vous.

Remarque    Pour plus d'informations sur la création de pages d'erreur personnalisées, lisez l'article d'Eli Robillard, Rich Custom Error Handling with ASP.NET.
Remarque    Lorsqu'une exception non gérée se produit dans un service Web ASP.NET, l'événement
Error
n'est pas signalé aux modules HTTP ni, par conséquent, à ELMAH. En fait, l'exception est interceptée par le runtime ASP.NET et une erreur SOAP est renvoyée au client. Pour qu'une erreur soit enregistrée dans un service Web, vous devez créer une extension SOAP qui surveille les erreurs SOAP.

Outre l'enregistrement des détails relatifs aux exceptions non gérées, ELMAH propose également un ensemble de gestionnaires HTTP permettant de visualiser le journal des erreurs. Il existe une interface Web pour accéder au fichier journal, qui peut fournir la liste de toutes les erreurs non gérées, ainsi que des détails sur une erreur en particulier (voir les illustrations 1 et 2).

elmah_fig01.gif

Figure 1. Visualisation du journal des erreurs

elmah_fig02.gif

Figure 2. Visualisation d'une erreur

Ce journal des erreurs peut également être affiché sous la forme d'un RSS, ce qui permet à un administrateur de recevoir des notifications par le biais de son agrégateur RSS préféré lorsqu'une erreur se produit (voir l'illustration 3).

elmah_fig03.gif

Figure 3. Source des erreurs pour le RSS
Remarque    RSS (Really Simple Syndication) est une norme employant le format XML, généralement utilisée pour regrouper des nouvelles et d'autres types de contenu évolutif. Pour en savoir plus sur RSS, y compris sur les modalités de syndication de contenu avec RSS, et pour apprendre à créer un lecteur RSS de type Web, reportez-vous à Creating an Online News Aggregator with ASP.NET.

En résumé, cet article ne mentionne qu'un sous-ensemble de fonctions d'ELMAH, en insistant sur les composants clé. Vous pouvez télécharger le code complet proposé avec cet article et nous vous encourageons à l'analyser avec soin pour connaître les détails de l'implémentation. Il existe aussi un espace GotDotNet Workspace pour ELMAH sur le site http://workspaces.gotdotnet.com/elmah, à partir duquel vous pouvez participer à des discussions, signaler vos problèmes et rester informé quant aux modifications éventuelles.

Solutions existantes pour un enregistrement centralisé des erreurs

Bien que ASP.NET ne propose pas de fonctionnalités intégrées d'enregistrement et de visualisation des erreurs, Patterns & Practices Group de Microsoft a créé un système d'enregistrement des erreurs de type open source (code ouvert), appelé Exception Management Application Block (EMAB). EMAB (ou bloc applicatif de gestion des exceptions) a été conçu pour fonctionner avec des applications bureautiques et des applications Web .NET, mais on ne peut s'empêcher de penser que ses créateurs l'ont destiné avant tout aux premières ; l'idée d'une utilisation avec les applications Web semble être venue dans un deuxième temps car EMAB, par défaut, publie les détails des exceptions dans le journal des événements Windows. Si le journal des événements constitue un outil adapté pour stocker des informations brèves sur les exceptions survenues dans une application bureautique, la plupart des applications Web, notamment celles hébergées sur un serveur partagé au sein d'une société d'hébergement, l'évitent car son utilisation nécessite des autorisations spéciales pour que l'application ASP.NET puisse y écrire des informations. Certes, EMAB est suffisamment flexible pour que vous puissiez créer un éditeur personnalisé enregistrant les informations dans une base de données, mais il s'agit là d'une opération supplémentaire qui relève de votre rôle de développeur.

Remarque    ELMAH est fourni avec un module de journalisation pour Microsoft SQL Server 2000, dont nous parlerons ultérieurement. Avec ELMAH, vous pouvez aussi créer des loggers d'exception personnalisés, par exemple un logger qui enregistre les détails des exceptions dans un fichier XML sur le système de fichiers du serveur Web. En fait, vous pouvez étendre les fonctionnalités ELMAH de façon à utiliser le bloc EMAB, si vous avez déjà écrit un éditeur personnalisé pour EMAB et que vous vouliez l'utiliser.

La manière dont EMAB est employé pour enregistrer les informations sur les exceptions influence fortement la facilité de gestion et la capacité de réutilisation de l'application Web. Par exemple, une approche simpliste pour enregistrer les informations d'exceptions serait de placer un bloc try ...catch de part et d'autre de chaque bloc de code dans chaque page Web ASP.NET, en appelant EMAB dans la section catch.

private void Page_Load(object sender, EventArgs e)
{
 try {
  // Code that might cause an exception
 }
 catch (Exception ex) {
  // record exception information by calling exception logger library
 }
}

Or cette méthode est tout à fait imprudente car elle lie étroitement l'enregistrement des exceptions à chaque page Web ASP.NET, ce qui empêche sa réutilisation et la rend difficile à gérer. Il serait préférable d'utiliser EMAB dans l'événement Application_Error dans Global.asax. En effet, cette solution autorise une architecture plus souple, facile à gérer et réutilisable, puisque le code de publication des exceptions, au lieu de se trouver dans les pages Web ASP.NET, se situe dans un emplacement unique centralisé. Mais l'inconvénient de cette approche est qu'elle n'est pas enfichable. Pour ajouter cette fonctionnalité d'enregistrement des erreurs dans une autre application Web ASP.NET, vous devriez modifier le fichier Global.asax de l'application, ce qui exigerait une recompilation et un redéploiement.

Le but de cet article n'est pas de proposer un remplacement au dispositif EMAB. Nous cherchons davantage à souligner la modularité qu'il est possible de mettre en œuvre avec les gestionnaires et les modules HTTP. ELMAH montre bien comment il est possible, à partir d'une tâche courante comme l'enregistrement centralisé des erreurs, de créer plusieurs composants qui seront plus faciles à gérer et largement réutilisables. L'objectif de ELMAH est d'offrir des orientations pour rendre modulaires les fonctionnalités appropriées.

Brève présentation des gestionnaires et des modules HTTP

Avant d'examiner les éléments spécifiques de l'architecture ELMAH et de son implémentation, rappelons rapidement ce que sont les gestionnaires et les modules HTTP. Chaque fois qu'une demande arrive sur un serveur Web IIS, IIS examine son extension pour déterminer la marche à suivre. Pour du contenu statique comme des pages HTML, des fichiers CSS, des images, des fichiers JavaScript, etc., IIS traite la requête elle-même. Pour du contenu dynamique comme des pages ASP, des pages Web ASP.NET ou des services Web ASP.NET, IIS délègue la requête à une extension ISAPI spécifiée. Une extension ISAPI est un bloc de code non géré capable de restituer des requêtes d'un type particulier. Par exemple, l'extension ISAPI asp.dll a pour fonction de restituer des requêtes pour des pages Web ASP classiques ; en revanche, l'extension ISAPI aspnet_isapi.dll est appelée lorsqu'une requête concerne une ressource ASP.NET.

Outre les extensions ISAPI, IIS fait aussi appel à des filtres ISAPI. Un filtre ISAPI est un bloc de code non géré qui peut s'exécuter en réponse à des événements déclenchés par IIS. Pendant la durée de vie d'une requête, IIS passe par un certain nombre d'étapes qui déclenchent des événements. Ainsi, un événement se produit lorsque la requête atteint la première fois IIS, lorsqu'elle est sur le point d'être authentifiée, lorsque le contenu extrait va être renvoyé au client, et ainsi de suite. Les filtres ISAPI sont couramment utilisés pour fournir des fonctionnalités comme la réécriture d'URL, la compression, l'authentification et l'autorisation spécialisée, la journalisation spécialisée, etc.

Lorsqu'une demande de ressource ASP.NET parvient à IIS, elle est dirigée vers le moteur ASP.NET qui génère le contenu correspondant. Le moteur ASP.NET fonctionne comme IIS du fait qu'il déclenche un certain nombre d'événements à mesure que la requête suit le pipeline HTTP d'ASP.NET. En outre, le moteur ASP.NET délègue le processus de génération de la ressource demandée à une classe particulière. Mais là où IIS utilise des extensions et des filtres ISAPI non gérés, ASP.NET utilise des classes non gérées appelées gestionnaires et modules HTTP.

Un gestionnaire HTTP est une classe dont le rôle est de générer un type particulier de ressource. Par exemple, la classe code-behind d'une page Web ASP.NET est un gestionnaire HTTP capable de générer le balisage de cette page Web particulière. Pour plus de facilité, imaginez les gestionnaires comme des convertisseurs spécialisés capables de créer le balisage d'un type particulier de ressource.

Remarque    Pour plus d'informations sur les gestionnaires HTTP et certaines de leurs applications, reportez-vous à l'article Serving Dynamic Content with HTTP Handlers.

Un module HTTP est une classe qui peut exploiter les divers événements déclenchés lorsqu'une requête passe par les différentes étapes de son cycle de vie dans le serveur. L'événement Error est un exemple d'événement d'application ASP.NET qui se déclenche suite à l'apparition d'une exception non gérée, ce qui précisément intéresse ELMAH.

Remarque    Pour plus d'informations sur les modules HTTP et leur utilisation en vue d'implémenter la réécriture d'URL, reportez-vous à l'article Réécriture d'URL dans ASP.NET.

L'illustration 4 représente le pipeline HTTP dans ASP.NET. Vous constatez que le processus démarre au moment où une requête parvient à IIS. En supposant que la ressource demandée soit configurée pour être gérée par l'extension ISAPI d'ASP.NET, IIS envoie la demande à l'extension ISAPI aspnet_isapi.dll. Cette extension ISAPI passe ensuite la requête au moteur ASP.NET géré. Durant le cycle de vie de la requête, un ou plusieurs modules HTTP peuvent s'exécuter, en fonction de ceux qui ont été enregistrés et selon les événements auxquels ils ont souscrit. Enfin, le moteur ASP.NET détermine le gestionnaire HTTP qui est chargé de générer le contenu, en appelant le gestionnaire et en renvoyant le contenu généré à IIS, qui le renvoie au client demandeur.

elmah_fig04.gif

Figure 4. Flux de données dans le logger des erreurs

ELMAH permet un enregistrement centralisé des erreurs par le biais d'un module HTTP qui propose un gestionnaire pour l'événement Error. Lorsque l'événement se déclenche, ELMAH enregistre les détails de l'exception. ELMAH utilise aussi des gestionnaires HTTP qui doivent essentiellement générer des balises HTML et RSS pour afficher les informations du journal des erreurs.

Pour configurer une application Web existante afin qu'elle utilise des gestionnaires ou des modules, il convient de copier l'assembly du module ou du gestionnaire dans le répertoire /bin de l'application et d'ajouter quelques lignes de configuration dans le fichier Web.config.

Pour configurer les modules HTTP pour une application Web, incluez une section <httpModules> dans le fichier Web.config qui spécifie le type du module à ajouter :

<httpModules>
  <add name="ModuleName" type="ModuleType" />
</httpModules>

ModuleType est une chaîne qui décrit le type du module et se présente sous la forme d'un nom de classe entièrement qualifié (Namespace.ClassName) suivi du nom d'assembly. L'attribut type peut également inclure des informations de gestion de version et des données culturelles ainsi qu'un jeton de clé publique nécessaire pour les assemblys à nom fort. L'extrait de code suivant montre le paramétrage de <httpModules> à utiliser pour inclure le module d'enregistrement des erreurs ELMAH dans votre application ASP.NET.

<httpModules>
 <add name="ErrorLog" type="GotDotNet.Elmah.ErrorLogModule, 
  GotDotNet.Elmah, Version=1.0.5527.0, Culture=neutral, 
  PublicKeyToken=978d5e1bd64b33e5" />
</httpModules>

Il est possible d'utiliser un gestionnaire HTTP dans une application Web en ajoutant une section <httpHandlers> dans le fichier Web.config. Du fait qu'un gestionnaire HTTP génère un contenu pour un type particulier de ressource, l'élément <httpHandlers> contient un attribut path en plus d'un attribut type, pour signaler que les chemins d'accès aux fichiers ou les extensions doivent être mappés sur ce gestionnaire HTTP. Il y a aussi un attribut verb qui permet de limiter l'usage du gestionnaire à des types spécifiques de demandes HTTP, comme dans une requête GET ou POST. L'exemple suivant crée un gestionnaire HTTP qui est appelé pour toutes les requêtes émises vers des fichiers ayant l'extension .ashx.

<httpHandlers>
  <add verb="*" path="*.ashx" type="HandlerType" />
</ httpHandlers >

L'attribut type du gestionnaire HTTP est exprimé à l'aide des mêmes options de syntaxe que pour les modules HTTP. Les paramètres qui figurent dans le fichier Web.config peuvent également être insérés dans le fichier machine.config, ce qui a pour effet d'activer les gestionnaires et les modules pour toutes les applications Web du serveur. L'extrait de code suivant montre l'élément <httpHandlers> du fichier Web.config associé à la démonstration fournie avec les données de téléchargement. Il indique par ailleurs que les requêtes entrantes émises vers /elmah/default.aspx doivent être générées par la classe ErrorLogPageFactory.

<httpHandlers>
  <add 
    verb="POST,GET,HEAD" 
    path="elmah/default.aspx" 
    type="GotDotNet.Elmah.ErrorLogPageFactory, 
     GotDotNet.Elmah, Version=1.0.5527.0, Culture=neutral, 
     PublicKeyToken=978d5e1bd64b33e5" />
</httpHandlers>

Comme vous pouvez le constater, l'ajout de modules et de gestionnaires HTTP dans une application Web ASP.NET est très simple ; quelques secondes suffisent et aucun processus de recompilation ou de redéploiement de l'application ASP.NET n'est nécessaire. C'est pourquoi les modules et les gestionnaires HTTP sont un outil remarquable pour la réutilisation, ils permettent la mise au point d'applications modulaires formées de composants flexibles, faciles à gérer.

Examen de l'architecture ELMAH

L'architecture ELMAH comporte trois sous-systèmes :

  • Un sous-système d'enregistrement des erreurs
  • Un sous-système de modules HTTP
  • Un sous-système de gestionnaires HTTP

Le sous-système d'enregistrement des erreurs remplit deux fonctions : il enregistre les erreurs dans le journal et extrait les informations correspondantes de ce même journal. Le sous-système de modules HTTP est chargé de l'enregistrement d'une erreur lorsqu'une exception non gérée se produit dans l'application ASP.NET. Le sous-système de gestionnaire HTTP permet de restituer le journal des erreurs dans un format avec balises, offrant ainsi une interface Web avec le journal ainsi qu'une source de données RSS.

Comme le montre l'illustration 5, les sous-systèmes de modules HTTP et de gestionnaires HTTP utilisent l'un et l'autre le sous-système d'enregistrement des erreurs. Le sous-système de modules HTTP envoie des informations d'exception au sous-système d'enregistrement des erreurs, tandis que le sous-système de gestionnaires HTTP lit et restitue les informations d'erreur.

elmah_fig05.gif

Figure 5. Place du système d'enregistrement des erreurs

Pour mieux comprendre l'architecture ELMAH, examinons en détail chacun de ces trois sous-systèmes.

Le sous-système d'enregistrement des erreurs

Le sous-système d'enregistrement des erreurs consigne les erreurs dans le fichier journal et permet d'extraire des informations sur une erreur particulière ou un sous-ensemble d'erreurs. Cette fonctionnalité est rendue possible grâce à plusieurs classes :

  • ErrorLog : Cette classe abstraite fournit les méthodes contractuelles pour lire et écrire dans le journal.
  • Error : Cette classe contient des propriétés qui décrivent les détails d'une erreur spécifique.
  • ErrorLogEntry : Cette classe représente une instance Error particulière pour un ErrorLog spécifique. Le ErrorLogEntry regroupe essentiellement une instance Error avec l'instance ErrorLog d'où elle provient.

Examinons ces trois classes et la manière dont elles fonctionnent avec les modules HTTP et les sous-systèmes de gestionnaire HTTP pour fournir un utilitaire complet d'enregistrement centralisé des exceptions.

Regard sur la classe ErrorLog

Selon la configuration d'un projet ou la stratégie particulière adoptée, vous pouvez avoir besoin d'utiliser un support de sauvegarde différent pour le journal des erreurs. Sur un serveur de production par exemple, vous pouvez consigner les exceptions dans Microsoft SQL Server mais, sur un serveur de développement, il vous suffira de stocker les erreurs dans un ensemble de fichiers XML ou dans une base Microsoft Access. Pour vous permettre d'utiliser des supports de sauvegarde différents, le sous-système d'enregistrement des erreurs propose une classe de base abstraite, ErrorLog, qui définit les méthodes de base que tous les loggers d'erreurs ELMAH doivent implémenter. Ces méthodes sont :

  • Log(Error) : Consigne une erreur dans le support de sauvegarde. La classe Error représente des informations sur une exception non gérée ; nous parlerons de cette classe Error plus en détails dans un moment. Lors de l'enregistrement des informations d'erreur, la méthode Log() doit également affecter un identificateur unique à l'erreur.
  • GetError(id) : Renvoie des informations sur une erreur particulière stockée dans le journal.
  • GetErrors(...) : Renvoie un sous-ensemble d'erreurs du journal. Cette méthode est utilisée par le sous-système de gestionnaires HTTP pour afficher le journal des erreurs dans un format de page au lieu de présenter toutes les erreurs à la fois.

ELMAH est fourni avec deux implémentations de la classe ErrorLog :

  • SqlErrorLog : Enregistre les erreurs dans une base de données Microsoft SQL Server 2000 en utilisant le fournisseur System.Data.SqlClient. La classe SqlErrorLog a besoin de SQL Server 2000 car elle exploite certaines de ces fonctionnalités XML, mais il s'agit d'un détail de l'implémentation qu'il est possible de modifier.
  • MemoryErrorLog : Enregistre les erreurs dans la mémoire (RAM) de l'application. En d'autres termes, elle est liée à AppDomain de telle sorte que chaque application reçoit son propre journal privé. Il va sans dire que ce journal ne survit pas au redémarrage de l'application ni à la durée de la session, aussi est-il plus particulièrement employé pour tester et résoudre provisoirement les problèmes, là où d'autres implémentations risquent de ne pas fonctionner.

Vous pouvez utiliser l'un ou l'autre de ces loggers d'exceptions en ajoutant tout simplement quelques lignes dans le fichier Web.config de votre application Web ASP.NET. Si vous avez besoin de stocker les données détaillées des erreurs ailleurs que dans SQL Server ou dans la mémoire de l'application, vous pouvez créer un logger personnalisé. Pour mettre en œuvre un logger des erreurs pour ELMAH, créez une classe qui étend la classe ErrorLog et fournissez l'implémentation pour les méthodes Log(), GetError() et GetErrors() par rapport au support de sauvegarde souhaité.

Vous constatez que les sous-systèmes de modules HTTP et de gestionnaires HTTP interagissent directement avec la classe ErrorLog spécifiée, qu'il s'agisse de SqlErrorLog, de MemoryErrorLog ou de votre propre classe. Le module HTTP enregistre les informations d'exception en créant une instance Error et en la transmettant à la méthode Log() de ErrorLog. Les gestionnaires HTTP lisent les données détaillées concernant une ou plusieurs erreurs à l'aide des méthodes GetError() et GetErrors() de ErrorLog, qui renvoient une instance ErrorLogEntry spécifique ou un ensemble d'instances ErrorLogEntry.

Regard sur la classe Error

La méthode Log() de la classe ErrorLog attend en entrée un paramètre de type Error. Une classe Error personnalisée est utilisée à la place de la classe Exception fournie dans le .NET Framework car la classe Exception est plus adaptée pour communiquer des informations d'exceptions au niveau de la pile du code et pendant la durée de vie d'une application. Cependant, les objets Exception ne sont pas des éléments de stockage idéals pour un journal des exceptions en raison de certains aspects relatifs au stockage, au typage et à la portabilité. Certes, il serait possible de recourir à la sérialisation binaire pour stocker une instance Exception, mais cela nécessiterait la désérialisation de l'objet Exception sur une machine disposant des mêmes groupes de types et d'assemblys. Il s'agit là d'une contrainte inacceptable (notamment du point de vue de l'administration et de l'exploitation) car un journal et son contenu doivent être portables et pas simplement affichables sur une machine avec un runtime ou une configuration particulière. En outre, une instance Exception ne dispose pas toujours des informations annexes propres à une application Web, telles que les valeurs de la collection de ServerVariables de la demande Web en cours, et qui ont une valeur inestimable pour effectuer un diagnostic. Ainsi, pour résumer, la classe Error fonctionne comme substitut pour tous les types d'exception, en gardant les informations d'une exception survenue dans une application Web.

La liste complète des propriétés de Error est présentée dans le tableau 1.

Propriété Description
ExceptionInstance Exception représentée par cette erreur. Il s'agit d'une propriété de run-time qui n'est jamais conservée au-delà d'une instance de la classe.
ApplicationNameNom de l'application dans laquelle l'erreur s'est produite.
HostNameNom de la machine hôte sur laquelle l'erreur s'est produite. Une valeur par défaut appropriée est Environment.MachineName.
TypeType, classe ou catégorie de l'erreur. Généralement, le nom complet du type (sans la qualification d'assembly) de l'exception est fourni.
SourceSource de l'erreur, habituellement la même que dans la propriété Message d'un objet Exception.
MessageTexte court décrivant l'erreur, habituellement la même que dans la propriété Message d'un objet Exception.
DetailTexte détaillé de l'erreur, par exemple la trace de la pile complète.
UserUtilisateur qui était connecté à l'application au moment où l'erreur s'est produite, tel qu'il est renvoyé par Thread.CurrentPrincipal.Identity.Name.
TimeDate et heure auxquelles l'erreur s'est produite. Ces valeurs sont toujours exprimées dans l'heure locale.
StatusCodeCode d'état renvoyé dans l'en-tête de la réponse suite à l'erreur. Par exemple, 404 pour une erreur FileNotFoundException. Malheureusement, cette valeur ne peut pas toujours être déterminée avec certitude à partir d'une application ASP.NET. Dans quelques cas, cette valeur StatusCode peut être renvoyée comme étant nulle.
WebHostHtmlMessageMessage HTML par défaut que l'hôte Wet (ASP.NET) génère en l'absence de pages d'erreurs personnalisées.
ServerVariablesUne NameValueCollection de variables de serveur Web, telles que celles contenues dans HttpRequest.ServerVariables.
QueryStringUne NameValueCollection de variables de type chaîne de requête HTTP, telles que celles contenues dans HttpRequest.QueryString.
FormUne NameValueCollection de variables de formulaires, telles que celles contenues dans HttpRequest.Form.
CookiesUne NameValueCollection de cookies envoyés par le client, comme ceux contenus dans HttpRequest.Cookies.

La propriété WebHostHtmlMessage mérite quelques explications. Si votre application ASP.NET rencontre une exception non gérée et si elle n'est pas configurée pour utiliser des pages d'erreur personnalisées, vous obtenez un écran semblable à celui de l'illustration 6. Il s'agit d'un écran auquel les développeurs en ASP.NET sont trop souvent confrontés.

elmah_fig06.gif

Figure 6. Page d'erreur standard

Lorsqu'une exception se produit, le système accède au balisage HTML réel de l'écran correspondant et celui-ci est enregistré dans la propriété WebHostHtmlMessage de la classe Error. Lorsque la page qui affiche les informations détaillées sur une exception spécifique est consultée, si l'instance Error correspondante a une valeur dans sa propriété WebHostHtmlMessage, le visiteur se voit proposer un lien d'accès à une page qui affiche l'écran des informations réelles de l'exception (comme celui de l'illustration 6). Le point intéressant ici est que non seulement l'exception est enregistrée, mais vous pouvez aussi consulter la page d'erreur originale générée par ASP.NET lorsque vous examinez le journal. Et tout ceci alors que vous avez activé les messages d'erreur personnalisés !

La classe Error contient aussi des méthodes pour sérialiser et désérialiser son état depuis et vers un format XML. Pour plus d'informations, reportez-vous à FromXml et ToXml dans le code d'accompagnement.

La classe ErrorLogEntry : association d'une erreur avec un journal d'erreurs

La classe finale dans le système d'enregistrement des erreurs est la classe ErrorLogEntry, qui associe une instance Error à une instance ErrorLog. Lorsque le sous-système de gestionnaires HTTP appelle la méthode GetError() pour extraire des informations sur une exception, la méthode GetError() extraite les informations du support de sauvegarde approprié et les insère dans une instance ErrorLogEntry. La classe ErrorLogEntry comporte trois propriétés :

  • Id : ID unique associé aux détails de l'exception.
  • Log : Référence à l'instance ErrorLog qui représente le support de sauvegarde.
  • Error : Une instance de la classe Error remplie avec les détails de l'erreur spécifique.

Alors que la méthode GetError() renvoie une instance ErrorLogEntry unique, GetErrors() renvoie une liste d'instances ErrorLogEntry. GetErrors() est spécialement conçue pour permettre aux erreurs de figurer dans n enregistrements à la fois.

L'illustration 7 montre une vue mise à jour de l'architecture ELMAH, avec notamment des détails dans le sous-système d'enregistrement des erreurs.

elmah_fig07.gif

Figure 7. Architecture mise à jour

Le sous-système de modules HTTP

ELMAH comprend deux modules HTTP : ErrorLogModule et ErrorMailModule. ErrorLogModule est un module HTTP qui crée un gestionnaire d'événements pour l'événement Error de l'application. Dans le cas où une exception non gérée survient, le module HTTP obtient le logger d'erreurs approprié, tel qu'il est spécifié dans la configuration de l'application, et appelle la méthode Log() sur celui-ci, en transmettant une instance Error contenant les informations de l'exception et le HttpContext de la demande en cours. Le code source suivant montre le code apparenté extrait de la classe ErrorLogModule :

public class ErrorLogModule : IHttpModule
{
  public virtual void Init(HttpApplication application)
  {
    application.Error += new EventHandler(OnError);
  }

  protected virtual ErrorLog ErrorLog
  {
    get { return ErrorLog.Default; }
  }

  protected virtual void OnError(object sender, EventArgs args)
  {
    HttpApplication application = (HttpApplication) sender;
    LogException(application.Server.GetLastError(), 
     application.Context);
  }

  protected virtual void LogException(Exception e, 
   HttpContext context)
  {
    try
    {
      this.ErrorLog.Log(new Error(e, context));
    }
    catch (Exception localException)
    {
      Trace.WriteLine(localException);
    }
  }
}

L'exécution de ErrorLogModule commence dans la méthode Init(), qui donne instruction au runtime ASP.NET d'appeler la OnError() chaque fois que l'événement Error se produit. La méthode OnError() référence l'objet HttpApplication et appelle la méthode LogException(), en transmettant les détails de la dernière exception, ainsi que l'instance HttpContext spécifique de la requête. LogException() appelle simplement la méthode Log() de la classe ErrorLog en passant une nouvelle instance Error. (Le constructeur de l'instance Error accepte en entrée une instance Exception et une instance HttpContext et fournit les propriétés en conséquence ; pour plus d'informations, reportez-vous au code source fourni avec les données de téléchargement.)

ErrorLogModule contient une propriété ErrorLog en lecture seule et renvoie une instance ErrorLog renvoyée par ErrorLog.Default. Default est une propriété statique du type ErrorLog dans la classe ErrorLog. Elle consulte la configuration de l'application Web afin de déterminer la classe à utiliser pour l'enregistrement des exceptions : SqlErrorLog, MemoryErrorLog ou une classe personnalisée.

Remarque    Dans la section Ajout de ELMAH dans une application Web ASP.NET, nous verrons comment configurer une application Web pour utiliser un logger d'exceptions spécifique. Il suffit d'ajouter quelques lignes dans les fichiers
Web.config
ou
machine.config
.

L'autre module HTTP du sous-système des modules HTTP est la classe ErrorMailModule, qui envoie un courrier électronique à un administrateur en cas d'exception. Nous n'aborderons pas cette partie de ELMAH, bien que nous puissions en étudier l'utilisation dans des exemples de code fournis avec les données du téléchargement.

Le sous-système de gestionnaires HTTP

Rappelons que le but des gestionnaires HTTP est de générer le contenu d'un type particulier de ressource. Lorsqu'une demande arrive dans le pipeline HTTP de l'ASP.NET, le moteur ASP.NET examine le chemin demandé et détermine le gestionnaire HTTP à utiliser pour traiter la ressource demandée. Notamment, une application ASP.NET peut être configurée pour qu'un chemin particulier soit traité par un gestionnaire HTTP ou une fabrique de gestionnaires HTTP. Une fabrique de gestionnaires HTTP est une classe qui n'est pas directement chargée de restituer le contenu mais qui doit en fait sélectionner en renvoyer une instance de gestionnaire HTTP. C'est cette instance renvoyée qui a pour tâche de restituer la ressource demandée.

Le sous-système de gestionnaires HTTP de ELMAH comprend un certain nombre de classes de gestionnaires HTTP pour générer les balises permettant d'afficher les erreurs enregistrées, ainsi qu'une classe de fabrique de gestionnaires HTTP. La classe de fabrique de gestionnaires HTTP, ErrorLogPageFactory, examine la partie PathInfo de l'URL demandée pour déterminer le gestionnaire qui doit générer la sortie.

Remarque    La partie
PathInfo
d'une URL est un contenu supplémentaire qui suit le nom de fichier et qui est accessible par le biais de la propriété PathInfo de l'objet
Request
. Par exemple, dans l'URL
http://www.example.com/someDir/somePage.aspx/somePath
, somePath est la partie
PathInfo
de l'URL. Pour plus d'informations sur la terminologie employée concernant les différentes parties d'une URL et sur les propriétés de l'objet
Request
correspondant, reportez-vous à l'article Making Sense of ASP.NET Paths de Rick Strahl.

L'extrait de code suivant montre la partie intéressante du code de la classe de fabrique de gestionnaires HTTP ErrorLogPageFactory.

public class ErrorLogPageFactory : IHttpHandlerFactory
{
  public virtual IHttpHandler GetHandler(HttpContext context, 
   string requestType, string url, string pathTranslated)
  {
    string resource = 
     context.Request.PathInfo.Length == 0 ? string.Empty :
      context.Request.PathInfo.Substring(1);

    switch (resource.ToLower(CultureInfo.InvariantCulture))
    {
      case "detail" :
        return new ErrorDetailPage();

      case "html" :
        return new ErrorHtmlPage();

      case "rss" :
        return new ErrorRssHandler();

      default :
        return new ErrorLogPage();
    }
  }
}

Comme vous pouvez le voir, la méthode GetHandler() de la classe ErrorLogPageFactory renvoie une instance de gestionnaire HTTP basée sur la valeur de PathInfo de la requête. Si PathInfo est du rss, une instance du gestionnaire HTTP ErrorRssHandler est renvoyée, qui restitue le journal sous la forme de données RSS. Si PathInfo est égal à detail, une instance du gestionnaire HTTP ErrorDetailPage est renvoyée et affiche des informations sur une exception particulière.

Dans les paramètres de l'application Web ASP.NET, vous devez spécifier un chemin mappé sur la fabrique de gestionnaires HTTP ErrorLogPageFactory, par exemple ErrorLog.aspx. Pour visualiser la source de données RSS du journal des exceptions, vous pouvez vous reporter au site : http://www.example.com/ErrorLog.aspx/rss.

Les diverses classes des gestionnaires HTTP de ELMAH (ErrorDetailPage, ErrorHtmlPage, ErrorRssHandler, ErrorLogPage, etc.) génèrent des balisages différents. Ainsi, le gestionnaire HTTP ErrorRssHandler exécute une boucle sur les 15 dernières erreurs et émet des balises XML adéquates pour afficher ces informations au format RSS. Les autres gestionnaires HTTP sont tous dérivés, directement ou indirectement, de la classe System.Web.UI.Page (qui est celle à partir de laquelle sont dérivées toutes les classes code-behind ASP.NET). Ces gestionnaires HTTP associés à une page remplace les méthodes Render() et OnLoad() de la classe Page pour créer une interface HTML qui affiche, sous la forme de pages, la liste des exceptions enregistrées. Reportez-vous aux figures 1, 2 et 3 qui présentent une illustration de ces pages.

Remarque    Alors que la classe
Error
sauvegarde les collections
ServerVariables
,
QueryString
,
Form
et
Cookie
, seule la collection
ServerVariables
s'affiche en détail pour une exception. Ceci s'explique du fait que les paramètres
QueryString
et les cookies sont visualisables par le biais des paramètres
QUERY_STRING
et
HTTP_COOKIE
de
ServerVariable
, respectivement. La collection
Form
est omise car elle risquerait de rajouter des dizaines de kilo-octets d'informations d'état qui présentent en général peu d'intérêt dans la plupart des diagnostics. Mais naturellement, vous pouvez facilement modifier les données du gestionnaire HTTP afin d'y inclure ces informations si vous le souhaitez.

Maintenant que nous avons examiné les trois sous-systèmes ELMAH, voyons comment ajouter ELMAH dans une application Web ASP.NET existante. Observez combien il est facile d'ajouter ELMAH dans un site, grâce à la modularité qu'autorisent les gestionnaires et modules HTTP.

Ajout de ELMAH dans une application Web ASP.NET

L'ajout de ELMAH dans une application Web ASP.NET est relativement simple et comprend deux étapes :

  • L'ajout de l'assembly ELMAH dans l'application Web.
  • La configuration de l'application Web afin qu'elle utilise les modules et les gestionnaires HTTP d'ELMAH.

ELMAH peut être appliqué à une application Web particulière sur un serveur Web ; il suffit de copier l'assembly dans le répertoire /bin de l'application et de configurer les paramètres ELMAH via le fichier Web.config. De plus, vous pouvez configurer ELMAH pour qu'il s'applique à toutes les applications Web d'un serveur Web en ajoutant l'assembly dans le cache global des assemblys (GAC, Global Assemby Cache) du serveur Web et en ajoutant les mêmes paramètres de configuration dans machine.config au lieu de Web.config.

Dans le fichier Web.config (ou machine.config), vous devez ajouter les paramètres suivants :

  • Un élément <sectionGroup> dans l'élément <configSections> pour définir un nouveau nom de section, <gotdotnet.elmah>, avec une section à l'intérieur de celui-ci appelée <errorLog> et contenant des instructions sur la manière d'enregistrer les informations d'exception.
  • Une section <gotdotnet.elmah> contenant une section nommée <errorLog> dans laquelle figure une référence de type au logger d'exceptions que doit utiliser ELMAH, ainsi que des paramètres spécifiques à ce logger.
  • Une entrée dans la section <httpHandlers> indiquant le chemin qui, lorsque vous passez par un navigateur, renvoie les différentes vues du journal des erreurs.
  • Une entrée dans la section <httpModules> qui ajoute ErrorLogModule dans le pipeline HTTP d'ASP.NET.

L'extrait de code suivant extrait du fichier Web.config fourni avec les données de téléchargement montre comment spécifier ces quatre paramètres.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
  <!-- Allows for a new section group to the Web.config -->
  <sectionGroup name="gotdotnet.elmah">
   <!-- Indicates that inside the section group there will be an
       errorLog section -->
   <section name="errorLog" 
    type="System.Configuration.SingleTagSectionHandler, 
     System, Version=1.0.5000.0, Culture=neutral, 
     PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
 </configSections>

 <!-- This section group contains the type of the exception logger
     to use (SqlErrorLog, MemoryErrorLog, or a custom logger).
     It also contain properties pertinent to the exception logger
     (connectionString, for the SqlErrorLog). -->
 <gotdotnet.elmah>
  <errorLog type="GotDotNet.Elmah.SqlErrorLog, 
   GotDotNet.Elmah, Version=1.0.5527.0, Culture=neutral, 
   PublicKeyToken=978d5e1bd64b33e5" 
   connectionString="...connection string..." />
 </gotdotnet.elmah>

 <system.web>
  <!-- Register that a request to aspnetham/errorlog.aspx should
    be serviced by the ErrorLogPageFactory HTTP Handler factory -->
  <httpHandlers>
   <add verb="POST,GET,HEAD" path="elmah/default.aspx" 
    type="GotDotNet.Elmah.ErrorLogPageFactory, 
    Skybow.Samples.AspNetHam, Version=1.0.5527.0, 
    Culture=neutral, PublicKeyToken=978d5e1bd64b33e5" />
  </httpHandlers>

  <!-- Adds the ErrorLogModule HTTP Module to the HTTP pipeline. -->
  <httpModules>
   <add name="ErrorLog" type="GotDotNet.Elmah.ErrorLogModule, 
     GotDotNet.Elmah, Version=1.0.5527.0, Culture=neutral, 
     PublicKeyToken=978d5e1bd64b33e5" />
  </httpModules>
  
  ...
 </system.web>
</configuration>

L'élément <sectionGroup> de l'élément <configSections> indique qu'il y aura un groupe de sections supplémentaires dans le fichier de configuration, appelé <gotdotnet.elmah>. En outre, il précise que cette section personnalisée va contenir une section <errorLog>. À l'intérieur de l'élément <gotdotnet.elmah> réel figure un élément <errorLog> qui spécifie l'implémentation du journal des erreurs à utiliser. N'oubliez pas que ELMAH est fourni avec deux implémentations intégrées, SqlErrorLog et MemoryErrorLog. Vous pouvez préciser celle que vous voulez utiliser ou désigner dans l'élément <errorLog> un logger d'exceptions que vous aurez vous-même créé. L'élément <errorLog> contient également les paramètres spécifiques à l'implémentation d'un journal des erreurs. Par exemple, si vous utilisez <errorLog> pour demander l'utilisation de SqlErrorLog, vous devez inclure une propriété connectionString afin de spécifier comment établir la connexion à la base de données. Le script SQL permettant de créer la table appropriée et les procédures stockées associées est inclus dans les données du téléchargement.

Remarque    Pour que l'administrateur soit informé par courrier électronique de l'existence d'une exception non gérée, vous devez ajouter un autre élément
<section>
dans
<sectionGroup>
qui définit un nouvel élément appelé
<errorMail>
. De plus, dans l'élément
<gotdotnet.elmah>
existant, vous devrez probablement ajouter un élément
<errorMail>
. Pour avoir un exemple de la syntaxe, consultez le fichier
Web.config
inclus dans les données du téléchargement.

La section <httpHandlers> spécifie le ErrorLogPageFactory (une fabrique de gestionnaires HTTP) à utiliser pour extraire le gestionnaire HTTP qui va générer le contenu et permettre de visualiser le journal d'erreurs. La valeur de l'attribut path indique l'URL relative à la racine virtuelle de l'application pour accéder à l'affichage du journal. Vous pouvez modifier cette information à tout moment, mais l'URL fournie doit dans tous les cas avoir une extension reconnue par le moteur ASP.NET. Ainsi, si vous remplacez le chemin par une information du type errors.log, vous devrez configurer IIS pour permettre le mappage des requêtes envoyées à errors.log vers l'extension ISAPI ASP.NET (aspnet_isapi.dll). Pour vous assurer que seuls les administrateurs affichent le journal, utilisez les fonctionnalités d'autorisation URL d'ASP.NET pour restreindre l'accès à un ou quelques utilisateurs ou rôles. En revanche, si vous envisagez de désactiver totalement l'accès Web au journal, il suffit de ne pas configurer la section <httpHandlers>.

La section <httpModules> ajoute le module HTTP ErrorLogModule dans le pipeline HTTP d'ASP.NET. Veillez à bien inclure ce paramètre <httpModules> ; en son absence, ELMAH ne surveille pas l'événement Error et n'enregistre donc pas les exceptions non gérées.

Comme vous le constatez, l'ajout de ELMAH dans une application Web ASP.NET existante est relativement simple. La facilité de déploiement et de réutilisation de ELMAH vient de sa modularité, basée sur l'emploi de modules et de gestionnaires HTTP.

Conclusion

J'espère que cet article a fait quelque peu la lumière sur l'utilité des gestionnaires et des modules HTTP pour produire une fonctionnalité modulaire orthogonale à une application Web ASP.NET. Les tâches courantes, comme l'enregistrement centralisé des messages ou la surveillance des requêtes à l'échelle de l'application peuvent être rendues modulaires, grâce aux gestionnaires et aux modules. L'encapsulation de cette fonctionnalité dans un ensemble de composants en facilite la réutilisation, la gestion et le déploiement, tout en vous évitant d'avoir à migrer, à intégrer ou à recompiler le code et les applications existantes.

Pour montrer qu'il est possible d'opter pour la modularité avec des modules et des gestionnaires HTTP, nous avons analysé ELMAH, une application de messagerie et d'enregistrement centralisé des erreurs. ELMAH utilise un module HTTP pour surveiller au niveau de l'application les événements Error qui se déclenchent lorsqu'une exception non gérée se produit. Lorsqu'il détecte une exception non gérée, ELMAH l'enregistre dans une base de données SQL Server, en mémoire ou, éventuellement, dans un autre support de sauvegarde. ELMAH peut également envoyer par messagerie électronique le contenu de l'exception à un ou plusieurs destinataires, développeurs ou personnel d'exploitation par exemple.

Outre un module HTTP, ELMAH contient un ensemble de gestionnaires HTTP et une fabrique de gestionnaires HTTP pour faciliter la consultation du journal des erreurs par le biais d'un outil Web. Il peut s'agir non seulement d'une page Web classique, mais également de données RSS. ELMAH gère un composant discret en encapsulant la fonctionnalité d'affichage dans un gestionnaire HTTP, au lieu de passer par l'application Web pour qu'elle affiche les informations dans une page Web ASP.NET. Grâce aux gestionnaires HTTP, le déploiement de ELMAH est un processus simple qui n'exige pas la recompilation de l'application Web ni le téléchargement d'une page ASP.NET sur le serveur de production.

ELMAH n'est qu'un exemple de ce que les gestionnaires et modules HTTP permettent d'obtenir en matière de modularité. Peut-être avez-vous implémenté vous-même des processus applicatifs susceptibles de profiter de cette modularité ?

Bonne programmation !

Remerciements

Avant de soumettre cet article à l'éditeur MSDN, plusieurs personnes de bonne volonté nous ont aidés à le relire et à vérifier son contenu, la grammaire et l'orientation générale. Les principaux collaborateurs du processus de révision sont Milan Negovan, Carl Lambrecht, Dominique Kuster, Roman Mathis, Raffael Zaghet, Muhammad Abubakar et Patrick Schuler.

Références

Bibliographie

Atif Aziz a près de 13 ans d'expérience dans le domaine du développement de solutions sur la plate-forme Microsoft. Il est consultant principal chez Skybow AG et son travail consiste avant tout à aider les clients à comprendre et à construire des solutions sur la plate-forme de développement .NET. Atif travaille régulièrement en collaboration avec les développeurs Microsoft en intervenant lors de conférences Microsoft ou non Microsoft et en écrivant des articles pour des publications techniques. Il est conférencier de l'INETA et président du plus grand groupe d'utilisateurs suisses .NET (dotMUGS). Vous pouvez le contacter à l'adresse atif.aziz@skybow.com ou sur son site Web http://www.raboof.com/.

Scott Mitchell, auteur de cinq ouvrages sur ASP/ASP.NET et fondateur de 4GuysFromRolla.com, utilise les technologies Web de Microsoft depuis 1998. Scott est à la fois consultant indépendant, formateur et écrivain. Vous pouvez le contacter à l'adresse mitchell@4guysfromrolla.com ou via son blog accessible à l'adresse http://scottonwriting.net/.

 

 



Dernière mise à jour le vendredi 17 décembre 2004



Afficher: