FAQ ASP.NET/C#

FAQ ASP.NET/C#Consultez toutes les FAQ
Nombre d'auteurs : 39, nombre de questions : 371, dernière mise à jour : 15 juin 2021
Sommaire→WebForms→Application→Gestionnaire HTTP et modules HTTP- 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 :
using System;
using System.Web;
namespace MonNamespace
{
public class MonHandler : IHttpHandler
{
public void ProcessRequest(System.Web.HttpContext context)
{
HttpResponse response = context.Response;
response.Write("<html><body>Hello world depuis mon handler</body></html>") ;
}
public bool IsReusable
{
get {return true;}
}
}
}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 :
namespace demoImg
{
public class HttpHandlerImage : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpServerUtility server = context.Server;
string idimage = request.QueryString["idimage"];
System.Drawing.Image img;
ImageFormat format; // par ex : ImageFormat.Jpeg
string contentType; // par ex : "image/jpeg"
LireImageDepuisLaBD(idimage, out img, out format, out contentType);
if (img != null)
{
context.Response.ContentType = contentType;
img.Save(context.Response.OutputStream, format);
}
else
context.Response.StatusCode = 404;
}
public bool IsReusable
{
get { return true; }
}
}
}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 : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = (HttpApplication) sender;
Debug.WriteLine(string.Format("Début de la requête pour {0} : {1}",
httpApplication.Context.Request.Url.ToString(), DateTime.Now.ToLongTimeString()));
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = (HttpApplication)sender;
Debug.WriteLine(string.Format("Fin de la requête pour {0} : {1}",
httpApplication.Context.Request.Url.ToString(), DateTime.Now.ToLongTimeString()));
}
public void Dispose()
{
}
}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 void Init(HttpApplication context)
{
SessionStateModule sessionMod = context.Modules["Session"];
sessionMod.Start += OnSessionStart;
// ...
}


