OutputCache et ScriptManager – Attention, seul le rendu est caché
Lorsque j’utilise un UserControl et que j’ai besoin d’inclure des scripts JavaScript, j’utilise un ScriptManagerProxy. L’avantage du ScriptManagerProxy est qu’il n’inclut le script qu’une seule fois, qu’importe si le UserControl se répète ou si l’on inclut le même script via un autre ScriptManagerProxy.
Récemment j’ai eu besoin d’activer du cache ASP.net sur un tel UserControl. J’ai donc utilisé la directive @OutputCache afin de mettre en place ce cache. Mon UserControl ressemblait alors à ceci :
<%@ Control Language="C#" %>
<%@ OutputCache Duration="60" VaryByParam="none" %>
<asp:ScriptManagerProxy runat="server">
<Scripts>
<asp:ScriptReference Path="~/js/pouet.js" />
</Scripts>
</asp:ScriptManagerProxy>
<%= DateTime.Now.ToLongTimeString() %>
Lors du premier affichage d’une page contenant cet UserControl, tout se passe bien, le script est correctement chargé. Par contre si j’actualise cette page, alors mon UserControl provient du cache mais le script JavaScript, lui, n’est pas chargé.
Pourquoi ?
Afin de comprendre d’où vient le problème, il faut comprendre ce que fait la directive OutputCache. Lorsque ASP.net rencontre une telle directive, il va alors créer un contrôle héritant de PartialCachingControl. Ce contrôle va alors se charger de gérer le cache : si le rendu du contrôle est présent dans le cache ASP.net va utiliser le rendu HTML du UserControl présent en cache, sinon il va utiliser le UserControl.
C’est ici qu’est le problème : lorsqu’ASP.net utilise le cache, il n’exécute pas les différents événements du UserControl (Init, Load, …). Dans notre cas, le ScriptManagerProxy ajoute les scripts dans le ScriptManager de la page lors de son événement Load.
Ce problème est présent avec le ScriptManagerProxy, mais il se retrouve dès que vous modifier le HTML à l’extérieur du UserControl à partir de celui-ci. Si vous utilisez par exemple les fonctions du ScriptManager ou du ClientScript comme le RegisterClientScript, vous serez alors aussi confrontés à ce souci.
Comment faire ?
Il n’y a pas de solution à ce problème, il s’agit d’un “bug” by design. Si l’on souhaite rajouter du cache sur un UserControl utilisant un ScriptManagerProxy, il faut déplacer le ScriptManagerProxy au niveau de la page.
L’ajout de cache sur un UserControl n’est donc pas une chose bénigne, il faut bien s’assurer que les événements du UserControl ne modifie pas le HTML de la page.
Et vous, avez vous déjà rencontré de tel soucis ?