Vous êtes sur la page 1sur 6

201

Chapitre 7
Utilisation avance
des contrleurs
1. Introduction
Utilisation avance des contrleurs

Ce chapitre dtaille le fonctionnement interne d'ASP.NET MVC concernant


la rsolution et l'invocation des contrleurs. Ce chapitre poursuit l'tude du
traitement d'une requte commence dans le chapitre prcdent, en reprenant
l'tape d'instanciation, par le module HTTP UrlRoutingModule, du
gestionnaire HTTP par dfaut d'ASP.NET MVC, de type MvcHandler,
prenant en paramtre une instance de la classe RequestContext.
Une fois initi au cycle de vie d'un contrleur, le lecteur trouvera des informa-
tions sur l'extensibilit des types de retour des actions, sur l'utilisation des
filtres d'action et pour terminer, sur l'criture de contrleurs asynchrones.

2. Le cycle de vie d'un contrleur


Lorsque la mthode ProcessRequest, point d'entre d'un gestionnaire
HTTP, est appele au sein de la classe MvcHandler, le nom du contrleur
cibl depuis l'instance RequestContext est tout d'abord extrait. Une
mthode publique nomme GetRequiredString, expose par la classe
RouteData, est rserve cet usage.
202 ASP.NET MVC 4
Dveloppement dapplications Web en C#

C'est cette tape qu'un en-tte HTTP indiquant la version d'ASP.NET MVC
est automatiquement ajout la rponse (sous la cl X-AspNetMvc-Ver-
sion). Il est facile de dsactiver cet en-tte car la classe MvcHandler
contient une proprit statique boolenne appele DisableMvcRes-
ponseHeader, dont la valeur par dfaut est false. En dfinissant sa valeur
true, par exemple dans le fichier Global.asax, l'ajout de l'en-tte la r-
ponse sera alors omis.
MvcHandler.DisableMvcResponseHeader = true;

Les problmatiques souleves par la prsence de cet entte, donnant des infor-
mations sur la technologie utilise, sont davantage expliques dans le chapitre
Scurit.

2.1 La fabrication d'un contrleur

Une fois le nom du contrleur instancier trouv, le gestionnaire fait appel


la classe ControllerBuilder, disponible sous la forme du paradigme de
programmation Singleton. Cette classe expose une instance qui doit impl-
menter l'interface IControllerFactory via la mthode GetControl-
lerFactory. Elle permet galement de remplacer le type expos par dfaut
par une implmentation personnalise via ses deux surcharges SetControl-
lerFactory.
Le diagramme de classes suivant permettra au lecteur de conserver une vision
densemble pendant les explications qui suivent.

Editions ENI - All rights reserved


Utilisation avance des contrleurs 203
Chapitre 7

Remarque
Le fonctionnement interne de la classe ControllerBuilder, l'criture d'une
implmentation personnalise de l'interface IControllerFactory et son uti-
lisation pour la rsolution des contrleurs sont des thmes tudis dans le cha-
pitre ASP.NET MVC avanc. Remplacer l'implmentation de l'interface
IControllerFactory est un cas d'usage courant lorsqu'une libraire d'injec-
tion de dpendances est utilise.

L'interface IControllerFactory reprsente la stratgie utiliser pour g-


nrer une instance de contrleur. Elle correspond au contrat ci-dessous.
public interface IControllerFactory
{
IController CreateController(RequestContext requestContext,
string controllerName);
SessionStateBehavior
GetControllerSessionBehavior(RequestContext requestContext
string controllerName);
void ReleaseController(IController controller);
}

La classe utilise par dfaut par ASP.NET MVC et qui implmente l'interface
IControllerFactory est la classe DefaultControllerFactory de
l'espace de noms System.Web.Mvc.
204 ASP.NET MVC 4
Dveloppement dapplications Web en C#

Le but de la mthode CreateController est d'instancier et de retourner


une implmentation de l'interface IController partir des informations
contenues dans une instance de RequestContext et du nom de contrleur
qui a t extrait depuis les paramtres de la route.
tudier l'implmentation de cette mthode dans la classe Default-
ControllerFactory est trs instructif.
Outre les vrifications sur la validit des arguments qu'elle reoit, un appel est
d'abord fait une mthode GetControllerType. Cette mthode extrait
d'ventuelles informations sur l'espace de noms o le contrleur doit tre
recherch, dans le cas d'une route pour une aire particulire. Puis, elle utilise
les rsultats obtenus pour appeler la mthode interne GetControllerTy-
peWithinNamespaces.
En interne, cette mthode utilise une instance de la classe ControllerTy-
peCache. Pendant tout le cycle de vie de l'application, cette classe maintient
un cache de tous les types correspondant des contrleurs prsents dans
l'application. Ainsi, la recherche d'un contrleur et son instanciation peut tre
acclre puisque l'tape de rflexion n'est pas rejoue chaque fois. Ce cache
est constitu au premier appel de la mthode EnsureInitialized, qui a
lieu la premire rsolution d'un contrleur. Par dfaut, pour tre localis et
pour pouvoir tre instanci, un contrleur doit respecter les rgles suivantes :
Sa visibilit doit tre publique.
Il doit implmenter l'interface IController. C'est le cas de la classe de
base Controller mais aussi de la classe de base ApiController, utilise
avec Web API.
Le nom de la classe doit tre suffix du terme Controller. C'est pour cette rai-
son que la fentre de cration d'un nouveau contrleur propose automati-
quement de l'ajouter.

Editions ENI - All rights reserved


Utilisation avance des contrleurs 205
Chapitre 7

Remarque
Les conventions de nommage ont un rle important au sein d'ASP.NET MVC.
Lors du chapitre sur la Conception de vues, une convention importante
concernait la rsolution des vues devant tre nommes en fonction du nom
des actions et places dans un dossier du nom du contrleur. Pour les contour-
ner, les dveloppeurs n'ont d'autres choix que de donner leur propre impl-
mentation de ces fonctionnalits. Dans le cas prsent, il faudrait implmenter
l'interface IControllerFactory.

Le cache maintenu par la classe ControllerTypeCache est stock dans un


fichier XML nomm MVC-ControllerTypeCache.xml et qui est situ
dans le rpertoire temporaire du serveur Internet, dans un chemin du type :
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary
ASP.NET Files\front-release\d45c3dcb\e807656\UserCache.

L'exemple ci-dessous prsente un extrait de ce fichier de cache. Il contient une


liste d'assemblage avec leur nom complet, et pour chacun de ces assemblages,
la liste des types qui ont t trouvs comme tant des contrleurs utilisables.
206 ASP.NET MVC 4
Dveloppement dapplications Web en C#

<?xml version="1.0" encoding="utf-8"?>


<!--This file is automatically generated. Please do not modify
the contents of this file.-->
<typeCache lastModified="25/06/2013 19:35:47"
mvcVersionId="23916767-7e3a-4fab-ad85-0bb94082b2dd">
<assembly name="MonAssembly, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null">
<module versionId="baba59b6-5c8b-43d2-a5d3-87f2bf656b8e">
<type>Mes.Namespace.AccountController</type>
<type>Mes.Namespace.HomeController</type>
</module>
</assembly>
</typeCache>

Remarque
Le mme principe de mise en cache a lieu au lancement d'une application
lorsque la mthode AreaRegistration.RegisterAllAreas est appele.
Celle-ci se contente de chercher des classes drivant de la classe AreaRe-
gistration et place son cache dans un fichier MVC-AreaRegistrationTy-
peCache.xml qui est sauvegard au mme endroit que celui des contrleurs.

Si un seul type est trouv, il est retourn la mthode CreateController.


Si aucun type n'est trouv, c'est la valeur nulle qui est retourne, et c'est la
mthode CreateController de grer ce cas d'erreur. Si l'inverse, plus d'un
contrleur a t trouv lors de la recherche, il y a ambigit. C'est ce moment
que la fabrique de contrleurs lve l'exception CreateAmbiguousCon-
trollerException en spcifiant tous les types qui ont t trouvs pour la
route courante.

Editions ENI - All rights reserved