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).
Figure 1.
Visualisation du journal des erreurs
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).
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.
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.
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 |
| Exception | Instance 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. |
| ApplicationName | Nom de l'application dans
laquelle l'erreur s'est produite. |
| HostName | Nom de la machine hôte
sur laquelle l'erreur s'est produite. Une valeur par
défaut appropriée est Environment.MachineName. |
| Type | Type, 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. |
| Source | Source de l'erreur,
habituellement la même que dans la
propriété Message d'un
objet Exception. |
| Message | Texte court décrivant
l'erreur, habituellement la même que dans la
propriété Message d'un
objet Exception. |
| Detail | Texte détaillé de
l'erreur, par exemple la trace de la pile
complète. |
| User | Utilisateur qui était
connecté à l'application au moment où
l'erreur s'est produite, tel qu'il est renvoyé par
Thread.CurrentPrincipal.Identity.Name. |
| Time | Date et heure auxquelles
l'erreur s'est produite. Ces valeurs sont toujours
exprimées dans l'heure locale. |
| StatusCode | Code 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. |
| WebHostHtmlMessage | Message HTML par défaut
que l'hôte Wet (ASP.NET) génère en
l'absence de pages d'erreurs personnalisées. |
| ServerVariables | Une
NameValueCollection de variables de serveur Web,
telles que celles contenues dans
HttpRequest.ServerVariables. |
| QueryString | Une NameValueCollection de variables de
type chaîne de requête HTTP, telles que celles
contenues dans
HttpRequest.QueryString. |
| Form | Une NameValueCollection de variables de
formulaires, telles que celles contenues dans
HttpRequest.Form. |
| Cookies | Une 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.
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.
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_STRINGet 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