Ajax et Upload - part 2 : utilisation d'un UpdatePanel et d'un FileUpload
Dans un précédent post, j'ai expliqué comment uploader un fichier sans faire un submit complet du formulaire : Ajax et Upload - part 1. Je viens de poster sur aspfr une solution pour que les FileUpload fonctionnent avec les UpdatePanel.
ASP.net Ajax : UpdatePanel et FileUpload
Pour faire fonctionner tout ce petit monde, j'ai fait un nouveau contrôle qui hérite de FileUpload, rajouté un HttpModule et un brin de JavaScript.
Voici comment cela fonctionne : imaginez que vous avez une page avec un FileUpload, un UpdatePanel, un Label et un Button, lorsque vous cliquez sur le bouton vous voulez envoyer le fichier au serveur et écrire la taille du fichier envoyé dans le Label et tout ça sans faire un rafraichissement complet de la page. Voici comment cela se passe :
- l'utilisateur clique sur le bouton
- l'événement initializeRequest du PageRequestManager est déclenché
- j'annule la requête XMLHttpRequest que cela aurait du faire
- je créé une nouvelle iframe
- je modifie le formulaire pour qu'il post dans l'iframe (cf Ajax et Upload - part 1)
- je mets un flag dans un champ caché
- je redéclenche le postback qui se fait alors normalement
- La requête http, arrive au niveau de l'UploadModule
- L'évenement BeginRequest de l'UploadModule est declenché
- je détecte la requête grâce au flag du champ caché
- j'enregistre le contenu de la réponse dans un StringBuilder grâce à un Response.Filter
- La requête s'effectue normalement au niveau de la page
- L'évenement EndRequest de l'UploadModule est declenché
- Le contenu de la réponse est stocké dans le cache pendant 5 minutes, cette réponse est associée à un Guid
- L'uploadModule renvoie du HTML qui exécute la méthode CS.FileUpload.callBack en passant en paramètre l'id de la réponse
- L'iframe reçoit la réponse et exécute la méthode CS.FileUpload.callBack
- je mets un nouveau flag dans un champ caché suivi de l'id de la réponse
- je déclenche un vrai AsyncPostBack qui sera fait via XmlHttpRequest
- L'événement BeginRequest de l'UploadModule est declenché
- je détecte la requête grâce au flag du champ caché
- j'extrais l'id de la réponse demandé
- je renvoie la réponse stocké dans le cache
- je supprime la réponse du cache
- je mets fin à la requête
- Coté client, le PageRequestManager reçoit la réponse comme une réponse classique d'AsyncPostBack
- le PageRequestManager continue son exécution et rafraichit les différents UpdatePanels
Pour simplifier l'utilisation de mon contrôle on peut utiliser le TagMapping, qui remplacera tous les classiques FileUpload par mon FileUpload sans modifier les pages du projet. Cela a pour avantage de simplifier la mis en place de cette solution puisqu'il suffit de rajouter un HttpModule et un TagMapping dans le web.config.
Vous trouverez dans le zip associé à la source, le projet CSAjaxUpload ainsi qu'un site de test. Attention ce projet est un prototype, cela ressemble plus à un "proof of concept" qu'à une vrai solution. Je suis impatient d'avoir des retours sur ce projet :-)