FAQ ASP.NET/VB.NET
FAQ ASP.NET/VB.NETConsultez toutes les FAQ
Nombre d'auteurs : 38, nombre de questions : 369, dernière mise à jour : 16 juin 2021
- Qu'est-ce qu'un gestionnaire HTTP (HttpHandler) ?
- Qu'est-ce qu'un module HTTP (HttpModule) ?
- Dois-je plutôt utiliser un HttpModule ou bien le Global.Asax ?
- Comment créer un HttpHandler ?
- Comment afficher une image stockée en binaire, par exemple depuis une base de données ?
- Comment créer un HttpModule ?
- Comment accéder aux évenéments d'un module http depuis un autre module ?
Toutes les requêtes faites à une application ASP.NET sont gérées par un composant spécialisé : le gestionnaire HTTP (HttpHandler).
Le plus connu est le gestionnaire de page, il traite les requêtes faites aux pages ASPX, crée la page, les objets, exécute le code et renvoi le html final.
Il est possible de créer son propre HttpHandler afin de traiter des requêtes particulières.
Ca peut être le cas par exemple pour afficher des images qui ont besoin d'un traitement préalable (chargement depuis une base de données, redimensionnement, etc ...)
Note : 1 requête est traitée par un et un seul HttpHandler
Un modulle HTTP permet de traiter les requêtes faites à une application ASP.NET.
Chaque requête passe par le pipeline de requête et est traitée par chaque HttpModule. Ces modules ont l'opportunité de s'abonner aux événements du cycle de vie de la requête.
Un module Http permet également d'avoir accès à la réponse sortante et de la modifier.
Les plus connus sont ceux utilisés par ASP.NET pour la génération de scripts clients ou de mise en cache.
On peut être amené à développer un module Http dans le cadre d'une réécriture d'url par exemple, ou dans le cadre d'une traduction automatique, etc ...
Un HttpModule est un bon complément au Global.Asax.
Un module Http accède aux mêmes événements et aux mêmes éléments que le Global.Asax.
Pourquoi alors utiliser un HttpModule plutôt que le Global.Asax ?
La première chose qui vient à l'esprit est la réutilisabilité.
J'ai par exemple développé un module d'url rewriting, je peux facilement l'utiliser dans une autre application, simplement en le déclarant comme il faut (voir Comment créer un HttpModule).
Par contre, le Global.Asax aura accès à d'autres événements qui ne sont pas pris en charge par un HttpModule, comme par exemple Session_Start et Session_End.
Il permet également d'instancier des objets globaux disponibles dans l'ensemble de l'application.
La première chose à faire est de créer une classe qui implémente IHttpHandler.
La propriété IsReusable permet d'indiquer si une autre demande peut utiliser l'instance IHttpHandler.
La méthode ProcessRequest sera utilisée pour écrire le flux de sortie HTTP, dans l'exemple qui suit, on affichera simplement un hello world :
Namespace MonNamespace
Public Class MonHandler
Implements IHttpHandler
Public Sub ProcessRequest
(
ByVal context As HttpContext) Implements IHttpHandler.
ProcessRequest
Dim response As HttpResponse =
context.
Response
response.
Write
(
"<html><body>Hello world depuis mon handler</body></html>"
)
End Sub
Public ReadOnly Property IsReusable
(
) As Boolean Implements IHttpHandler.
IsReusable
Get
Return True
End Get
End Property
End Class
End Namespace
Pour l'utiliser, il faudra le déclarer dans le web.config à la section <httpHandlers> de <system.web> et le configurer de manière à ce qu'il réponde à une requête.
Par exemple, pour les requêtes qui contiendront hello.world :
<configuration>
<system.web>
<httpHandlers>
<add
verb
=
"*"
path
=
"hello.world"
type
=
"MonNamespace.MonHandler, MonAssembly"
/>
</httpHandlers>
<system.web>
</configuration>
Note, l'attribut verb permet de spécifier à quel type de requête le handler doit répondre (GET, POST, ou * (les deux))
On utilisera un handler qui s'occupera de renvoyer l'image.
Le handler répond à une requête pour lire l'image et s'occupe de la charger depuis la base de données. Ensuite, il renverra un contenu de type image qui pourra être affiché par la balise <img>.
Par exemple :
Imports System.
Drawing.
Imaging
Namespace demoImg
Public Class HttpHandlerImage
Implements IHttpHandler
Public Sub ProcessRequest
(
ByVal context As HttpContext) Implements IHttpHandler.
ProcessRequest
Dim request As HttpRequest =
context.
Request
Dim server As HttpServerUtility =
context.
Server
Dim idimage As String =
request.
QueryString
(
"idimage"
)
Dim img As System.
Drawing.
Image
Dim format As ImageFormat ' par ex : ImageFormat.Jpeg
Dim contentType As String ' par ex : "image/jpeg"
LireImageDepuisLaBD
(
idimage,
img,
format,
contentType)
If Not img Is Nothing Then
context.
Response.
ContentType =
contentType
img.
Save
(
context.
Response.
OutputStream,
format)
Else
context.
Response.
StatusCode =
404
End If
End Sub
Public ReadOnly Property IsReusable
(
) As Boolean Implements IHttpHandler.
IsReusable
Get
Return True
End Get
End Property
End Class
End Namespace
Il faudra déclarer le handler dans le web.config :
<httpHandlers>
<add
verb
=
"*"
path
=
"displayimg"
type
=
"demoImg.HttpHandlerImage,demoImg"
/>
</httpHandlers>
On pourra appeler le handler en utilisant par exemple :
<img src
=
"displayimg?idimage=1234"
/>
La première chose à faire est de créer une classe qui implémente IHttpModule.
Il est obligatoire d'implémenter les méthodes Init et Dispose.
Init nous permet de nous abonner aux événements qui nous intéressent, par l'intermédiaire de l'objet HttpContext.
Dans l'exemple qui suit, je trace le début et la fin d'analyse des requêtes grâce aux événements BeginRequest et EndRequest.
Public Class MonHttpModule
Implements IHttpModule
Public Sub Init
(
ByVal context As HttpApplication) Implements IHttpModule.
Init
AddHandler context.
BeginRequest,
New EventHandler
(
AddressOf context_BeginRequest)
AddHandler context.
EndRequest,
New EventHandler
(
AddressOf context_EndRequest)
End Sub
Private Sub context_BeginRequest
(
ByVal sender As Object,
ByVal e As EventArgs)
Dim httpApplication As HttpApplication =
sender
Debug.
WriteLine
(
String.
Format
(
"Début de la requête pour {0} : {1}"
,
_
httpApplication.
Context.
Request.
Url.
ToString
(
),
DateTime.
Now.
ToLongTimeString
(
)))
End Sub
Private Sub context_EndRequest
(
ByVal sender As Object,
ByVal e As EventArgs)
Dim httpApplication As HttpApplication =
sender
Debug.
WriteLine
(
String.
Format
(
"Fin de la requête pour {0} : {1}"
,
_
httpApplication.
Context.
Request.
Url.
ToString
(
),
DateTime.
Now.
ToLongTimeString
(
)))
End Sub
Public Sub Dispose
(
) Implements IHttpModule.
Dispose
End Sub
End Class
Pour que cette classe soit prise en compte par notre application, on va la définir dans le web.config à la section <system.web> :
<httpModules>
<add
name
=
"MonHttpModule"
type
=
"MonNamespace.MonHttpModule, MonAssembly"
/>
</httpModules>
L'objet d'application possède une propriété (Modules) contenant une collection avec tous les HttpModule de l'application.
On pourra accéder à un HttpModule en utilisant son nom. Ainsi, on pourra le référencer depuis un autre HttpModule et s'abonner à ses événements.
Public Sub Init
(
ByVal context As HttpApplication) Implements IHttpModule.
Init
Dim sessionMod As SessionStateModule =
context.
Modules
(
"Session"
)
AddHandler sessionMod.
Start,
New EventHandler
(
AddressOf OnSessionStart)
End Sub