Bewise

Nous développons... votre avance

WSS V3 - Utiliser le framework ASP .NET AJAX avec WSS 3.0

PTC
15/02/2007 - Laurent Cotton
Télécharger la version Word
Télécharger les sources

1 Introduction

Depuis la sortie de la version RTM du framework ASP .NET AJAX il y a quelques semaines, j’ai cherché comment faire pour intégrer le potentiel offert par ce framework dans des sites Windows SharePoint Services 3.0. Après quelques jours de tests, Alléluia, le miracle s’est produit.

Je me propose donc, aujourd’hui, de partager avec vous le résultat de cette étude et de vous fournir les clés qui vous permettront d’intégrer des « UpdatePanels » et autres nouveautés du framework ASP .NET AJAX dans WSS 3.0, soit directement dans des pages .aspx, soit dans des WebParts.

2 Environnement et pré-requis

Avant toute chose, la première étape à l’utilisation du framework ASP .NET AJAX, c’est d’installer ce dernier sur le serveur hébergeant WSS 3.0. Vous pouvez télécharger le framework AJAX depuis l’url suivante :

http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en

La plateforme que j’utilise dans le cadre de cet article est un serveur Windows Server 2003 US avec également une version US de WSS 3.0. Dans cet environnement, le répertoire d’installation par défaut de WSS est « C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12 ». Si vous travaillez sur une version FR de Windows Serveur 2003, le répertoire est « C:\Program Files\Fichiers Communs\Microsoft Shared\Web Server Extensions\12 ».

Un des répertoires auquel je ferai référence dans cet article est le répertoire contenant les fichiers javascript de WSS 3.0. Sur ma plateforme, ce répertoire est le sous répertoire « Template\Layouts\1033\ » du répertoire d’installation de WSS. Sur une installation FR de WSS, ce répertoire est « Template\Layouts\1036\ ». Pour simplifier la compréhension de l’article, je ferai par la suite référence à ce répertoire en le nommant « répertoire des scripts de WSS ».

J’ai également à ma disposition sur mon serveur une installation complète de Visual Studio 2005 Team Suite et de SharePoint Designer 2007.

3 Commençons

Bon, tout le monde est prêt ? Alors, c’est parti …

3.1 Création d’une nouvelle Application Web WSS

Je commence tout d’abord par créer, à l’aide de la console d’administration de WSS, une nouvelle Web Application WSS avec une collection de site basée sur le modèle « Site vide ». Voici ci-dessous à quoi ressemble la page d’accueil de ce site :

clip_image004

La prochaine étape va être maintenant de modifier le fichier de configuration de mon site web WSS pour ajouter toutes les informations nécessaires au framework ASP .NET AJAX pour fonctionner.

3.2 Modification du fichier web.config du site WSS

Pour ceux d’entre vous qui se sont déjà penchés sur le framework ASP .NET AJAX, vous avez sûrement dû remarquer qu’il est nécessaire d’ajouter de nombreuses informations dans le fichier de configuration d’un site ASP .NET standard pour qu’il puisse faire fonctionner de l’AJAX.

La copie d’écran ci-dessous présente, pour ceux d’entre vous qui ne connaissent pas, à quoi ressemble le fichier web.config d’un site ASP .NET AJAX par défaut.

clip_image006

clip_image008clip_image010

Bon, je sais que ça n’est pas super lisible, mais là n’est pas l’objectif. Le but est surtout de vous faire comprendre que la tâche n’est pas forcément aisée. Vous trouverez dans les sources de l’article un fichier « Ajax, default web.config » qui est une version lisible de la copie d’écran ci-dessus … :D

Bref ! Vous avez donc compris ce qui nous attend. La seconde étape est donc de venir fusionner le fichier de configuration de notre site WSS avec le fichier de configuration par défaut d’un site ASP .NET AJAX. Toujours dans les sources de l’article, vous trouverez les fichiers « Wss, original web.config » et « Wss, final web.config » qui sont, respectivement, le fichier de configuration d’origine de mon site WSS et le fichier de configuration WSS fusionné avec le fichier de configuration AJAX. Pour ce faire, nous allons ouvrir nos deux fichiers de configuration (celui par défaut d’AJAX et celui de notre site WSS) et procéder comme suit :

· Depuis le fichier de configuration AJAX, dans la section configuration\configSections, copiez la section sectionGroup complète et collez-la dans la section configuration\configSections du fichier de configuration de WSS.

· Depuis le fichier de configuration AJAX, dans la section configuration\system.web\pages, copiez la section controls complète et collez-la dans la section configuration\system.web\pages du fichier de configuration de WSS.

· Depuis le fichier de configuration AJAX, dans la section configuration\system.web\compilation\assemblies, copiez toutes les sections add et collez les dans la section configuration\system.web\compilation\assemblies du fichier de configuration de WSS. Attention, une des lignes copiées (déclaration de l’assemby Microsoft.SharePoint) existe déjà dans le fichier de configuration de WSS. Il faut donc la supprimer des lignes copiées.

· Depuis le fichier de configuration AJAX, dans la section configuration\system.web\httpHandlers, copiez toutes les sections add et collez-les dans la section configuration\system.web\compilation\httpHandlers du fichier de configuration de WSS. Attention : les lignes doivent être insérées après la ligne remove.

· Depuis le fichier de configuration AJAX, dans la section configuration\system.web\httpModules, copiez la ligne add et collez-la dans la section configuration\system.web\compilation\httpModules du fichier de configuration de WSS. Attention : la ligne doit être insérée après la ligne clear.

· Depuis le fichier de configuration AJAX, dans la section configuration, copiez la section system.webServer complète et collez-la dans la section configuration du fichier de configuration de WSS.

Voilà, c’est fait. Maintenant, il faut nous assurer que notre site WSS fonctionne toujours correctement. Pour cela, enregistrez les modifications faites sur le fichier de configuration du site WSS. Pour s’assurer que les modifications soient bien prises en compte, exécutez la commande IISRESET. Enfin, connectez-vous à votre site WSS … normalement, tout doit bien fonctionner. En cas d’erreur, vérifiez que le fichier de configuration est bien correct, et que vous n’avez pas commis d’erreur dans le copier-coller.

3.3 Mise en place du ScriptManager

OK, notre site WSS est configuré pour pouvoir exploiter le framework ASP .NET AJAX. Maintenant, il nous faut mettre en œuvre de l’AJAX dans notre site WSS. La première chose à faire est donc de mettre en place un contrôle AJAX ScriptManager. En effet, toute page web souhaitant exploiter les contrôles AJAX doit contenir un contrôle ScriptManager.

Afin de me simplifier la tâche, et n’avoir à gérer la présence du ScriptManager qu’une seule fois, j’ai décidé de le rajouter directement dans la master page par défaut de mon site WSS. Comment faire ? C’est très simple, vous allez voir. 

A l’aide de SharePoint Designer 2007, ouvrez votre site WSS. Ensuite, dans le répertoire _catalogs\masterpage, éditez la page default.master et placez-vous dans le code de cette page comme dans la copie d’écran ci-dessous.

clip_image012

De la même façon que la masterpage déclare un WebPartManager nécessaire à la gestion des WebParts, nous allons déclarer notre ScriptManager. Pour cela, ajoutons la ligne suivante juste au-dessus de la déclaration du WebPartManager :

<asp:ScriptManager ID="mainScriptManager" runat="server"/>

Vous devriez obtenir ceci :

clip_image014

Enregistrez les modifications et reconnectez-vous à votre site WSS pour tester que tout fonctionne. Hélas… non, vous obtenez une erreur WSS vous indiquant que le contrôle System.Web.UI.ScriptManager n’est pas « Safe ».

Comment corriger ce problème ? Là encore, rien de bien compliqué. Il nous suffit d’indiquer dans le fichier de configuration de notre site web que notre assembly System.Web.Extension (c’est l’assembly AJAX qui déclare le contrôle ScriptManager) est safe. Pour cela, éditons donc notre fichier web.config et ajoutons, dans la section configuration/SharePoint/SafeControls la ligne suivante :

<SafeControl Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" AllowRemoteDesigner="True" />

Enregistrez les modifications, un petit coup de IISRESET et re-testez votre site WSS. Le problème est bien corrigé. Nous pouvons passer à la suite…

3.4 Développement d’un WebPart « AJAX »

Nous pouvons maintenant créer un WebPart qui va utiliser les contrôles AJAX. Le web part que je vais développer ici n’a rien d’extraordinaire. Tout ce qu’il fait, c’est mettre à jour l’heure, mais sans rafraîchir toute la page. Ceci devrait nous permettre de vérifier que tout fonctionne correctement.

Je crée donc à l’aide de Visual Studio un nouveau projet de type Class Library. Ensuite, je vais ajouter les références aux assemblies :

· Microsoft.SharePoint (WSS)

· System.Web.Extensions (Contrôles AJAX)

· System.Web (Contrôles ASP .NET Standard)

Je crée ensuite une classe que je nomme WebPartHeure et que je fais hériter de la classe Microsoft.SharePoint.WebPartPages.WebPart. Je rajoute en entête de ma classe la directive using System.Web.UI et using System.Web.UI.WebControls. Mon WebPart va se constituer d’un label chargé d’afficher l’heure et d’un bouton permettant de mettre à jour l’heure. Afin de pouvoir faire le tout en AJAX, ces 2 contrôles seront inclus dans un UpdatePanel. Voici ci-dessous le code complet de WebPart.

using System; using System.Web.UI; using System.Web.UI.WebControls; namespace Bewise.Wss3.Sample.AjaxEtWss { public class WebPartHeure : Microsoft.SharePoint.WebPartPages.WebPart { private Label hour; private Button refreshHour; private UpdatePanel updatePanel; private AsyncPostBackTrigger refreshHourTrigger; protected override void CreateChildControls() { // Label hour = new Label(); hour.ID = "hour"; // Show datetime hour.Text = DateTime.Now.ToString(); // Button refreshHour = new Button(); refreshHour.ID = "refreshHour"; refreshHour.Text = "Refresh !"; // Trigger refreshHourTrigger = new AsyncPostBackTrigger(); refreshHourTrigger.ControlID = refreshHour.ID; refreshHourTrigger.EventName = "Click"; // UpdatePanel updatePanel = new UpdatePanel(); updatePanel.ID = "updatePanel"; updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional; // Add trigger to UpdatePanel updatePanel.Triggers.Add(refreshHourTrigger); // Add Childs controls updatePanel.ContentTemplateContainer.Controls.Add(hour); updatePanel.ContentTemplateContainer.Controls.Add(refreshHour); // Add all controls to te WebParts this.Controls.Add(updatePanel); } protected override void Render(HtmlTextWriter writer) { // Ensure childs controls are created this.EnsureChildControls(); // Render updatePanel and childs controls updatePanel.RenderControl(writer); } } }

N’oubliez pas de signer votre assembly sinon, vous ne pourrez pas la référencer dans WSS. Ensuite, créons un fichier .dwp pour pouvoir intégrer notre WebPart dans WSS. Voici le contenu de fichier (pour mon exemple).

<?xml version="1.0" encoding="utf-8" ?> <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2"> <Assembly>Bewise.Wss3.Sample.AjaxEtWss, Version=1.0.0.0, Culture=neutral, PublicKeyToken=995401eda3d8bd0c</Assembly> <TypeName>Bewise.Wss3.Sample.AjaxEtWss.WebPartHeure</TypeName> <Title>WebPartHeure AJAX</Title> <Description>Show hour and refresh using AJAX</Description> </WebPart>

3.5 Déployons notre WebPart

Maintenant que notre WebPart est près, il nous faut encore l’enregistrer dans WSS pour pouvoir le tester. Copiez le fichier .dwp ainsi que votre assembly dans le répertoire bin de votre site web WSS. Ceci fait, éditons le fichier de configuration du site pour déclarer notre assembly comme « Safe ». Pour ce faire, il faut ajouter la ligne suivante dans la section configuration/SharePoint/SafeControls puis enregistrer les modifications.

<SafeControl Assembly="Bewise.Wss3.Sample.AjaxEtWss, Version=1.0.0.0, Culture=neutral, PublicKeyToken=995401eda3d8bd0c" Namespace="Bewise.Wss3.Sample.AjaxEtWss" TypeName="*" Safe="True" AllowRemoteDesigner="True" />

Ensuite, ouvrez votre site WSS. Allons dans la galerie de WebPart du site et téléchargez-y votre fichier .dwp. Vous devriez le voir apparaître dans la liste des WebParts du site comme suit :

clip_image016

Retournez sur la page d’accueil du site et éditez-la. Ajoutez dans une des WebPart Zones disponibles une instance de votre WebPart. Enfin, quittez le mode édition. Vous devriez obtenir quelque chose de similaire.

clip_image018

Testons si tout marche bien… Hélas, et 100 fois hélas ! Si vous testez correctement, vous pouvez vous rendre compte que la première fois qu’on clique sur notre bouton « Refresh », tout se passe bien mais ensuite… plus rien. Pourquoi ?

3.6 Un effet de bord

Qu’est-ce qui peut bien se passer pour que mon WebPart fonctionne correctement la première fois et pas du tout les fois suivantes ? Après avoir passé plusieurs heures à chercher l’origine du problème, j’en ai finalement trouvé la source. Si on réédite à l’aide de SharePoint Designer la master page, on peut observer les 2 lignes suivantes :

<BODY scroll="yes" onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();">

et

<form runat="server" onsubmit="return _spFormOnSubmitWrapper();">

La seconde ligne signifie qu’à chaque submit d’une page WSS, la méthode javascript _spFormOnSubmitWrapper() est appelée. Cette méthode est déclarée dans le fichier INIT.JS du répertoire des scripts de WSS (cf. Introduction pour localiser ce répertoire). Voici le code de cette fonction :

function _spFormOnSubmitWrapper() { if (_spSuppressFormOnSubmitWrapper) { return true; } if (_spFormOnSubmitCalled) { return false; } if (typeof(_spFormOnSubmit)=="function") { var retval=_spFormOnSubmit(); var testval=false; if (typeof(retval)==typeof(testval) && retval==testval) { return false; } } RestoreToOriginalFormAction(); _spFormOnSubmitCalled=true; return true; }

Mais que fait donc cette fonction ? En plus de retourner true ou false en fonction de certaines conditions, on peut se rendre compte que la fonction met à jour la variable _spFormOnSubmitCalled à true. En cherchant encore, on trouve que cette même variable est réinitialisée à false dans la méthode _spBodyOnLoadWrapper() et que cette même méthode est appelée à chaque Load d’une page WSS (cf. première ligne). Mais quel est le problème ?

C’est simple ! En temps normal, sans AJAX, au chargement de la page, la variable _spFormOnSubmitCalled est initialisée à false par la méthode _spBodyOnLoadWrapper(). Ensuite, lors d’un postback, cette variable passe à true (méthode _spFormOnSubmitWrapper()) mais est réinitialisée à false lors du rechargement de la page (comme lors du premier chargement). Maintenant, pourquoi cela ne marche pas quand on utilise de l’AJAX. Là encore, rien de bien compliqué : au premier chargement de la page, la variable est bien positionnée à false. Ensuite, lorsqu’on clique sur notre bouton « Refresh », la méthode _spFormOnSubmitWrapper() positionne la variable à true. Par contre, la différence avec un postback normal, c’est que, à la fin du traitement AJAX, la méthode _spBodyOnLoadWrapper() n’est pas rappelée puisque la page n’est pas entièrement rechargée, donc, notre variable n’est pas repositionnée à false.

Et oui, tout ça à cause d’une simple variable …

3.7 Corrigeons le problème

Pour corriger le problème, il va nous falloir faire en sorte de laisser la variable spFormOnSubmitCalled à false s’il s’agit d’un submit « AJAX ». Nous allons donc ajouter la prise en compte du cas AJAX dans la méthode spFormOnSubmitWrapper().Voici ci-dessous le nouveau code de la fonction avec, en italique, les modifications apportées. Par sécurité et afin de pouvoir revenir en arrière en cas de problème, je vous conseille vivement de faire une copie du fichier INIT.JS avant toute modification.

function _spFormOnSubmitWrapper() { if (_spSuppressFormOnSubmitWrapper) { return true; } if (_spFormOnSubmitCalled) { return false; } if (typeof(_spFormOnSubmit)=="function") { var retval=_spFormOnSubmit(); var testval=false; if (typeof(retval)==typeof(testval) && retval==testval) { return false; } } if((typeof(Sys) != 'undefined' ) && (typeof(Sys.WebForms) != 'undefined' ) && (Sys.WebForms.PageRequestManager.getInstance() != null) && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != '')) _spFormOnSubmitCalled=false; else _spFormOnSubmitCalled=true; RestoreToOriginalFormAction(); _spFormOnSubmitCalled=true; return true; }

Que fait le code que nous avons rajouté ? Il regarde :

· si les types « Sys » et « Sys.WebForm » propres au framework AJAX sont définis,

· s’il existe une instance du ScriptManager (obligatoire pour faire de l’AJAX),

· si l’Id du panel ayant fait le submit est bien enregistré auprès du scriptManager (dans ce cas, le submit a été fait par un contrôle AJAX).

Si toutes ces conditions sont réunies, cela signifie que c’est bien un contrôle AJAX qui a fait le submit. Dans ce cas, nous positionnons la variable à l’origine du problème à false, sinon, on laisse le traitement par défaut.

Et voilà, après ça, tout devrait marcher parfaitement. Afin de vous rassurer sur les modifications faites au niveau du fichier INIT.JS, la variable incriminée n’est utilisée que par les 2 fonctions citées précédemment et nulle part ailleurs.

4 Vérifions

Bon, effectivement, tout a l’air de bien fonctionner, mais vérifions quand même. La copie d’écran ci-dessous montre la taille de la page default.aspx au premier chargement. On peut même vérifier sur la partie droite de l’écran que le serveur retourne bien la page en entier

clip_image020

Maintenant, la réponse du serveur après avoir cliqué sur notre bouton « refresh »

clip_image022

On peut effectivement constater que la taille de la réponse est bien moins grosse et que le serveur ne retourne pas toute la page.

5 Conclusion

Ben, rien de particulier à dire. J’espère que cet article va vous dépanner et vous permettre d’enrichir vos applications WSS. N’hésitez pas à me faire part de vos remarques et commentaires.

Amusez-vous bien et à bientôt pour un prochain article.

> Tous les articles

Commentaires

03/10/2008 par Antoine Seiter : Correction

Bonjour, Merci pour cet article très utile, par contre voici 2 remarques : 1) Il y a une petite coquille dans la fonction _spFormOnSubmitWrapper, la variable _spFormOnSubmitCalled est toujours définit à VRAI. Voici le code corrigé : function _spFormOnSubmitWrapper() { if (_spSuppressFormOnSubmitWrapper) { return true; } if (_spFormOnSubmitCalled) { return false; } if (typeof(_spFormOnSubmit)=="function") { var retval=_spFormOnSubmit(); var testval=false; if (typeof(retval)==typeof(testval) && retval==testval) { return false; } } RestoreToOriginalFormAction(); if((typeof(Sys) != 'undefined' ) && (typeof(Sys.WebForms) != 'undefined' ) && (Sys.WebForms.PageRequestManager.getInstance() != null) && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != '')) _spFormOnSubmitCalled=false; else _spFormOnSubmitCalled=true; return true; } 2) Cette fonction "_spFormOnSubmitWrapper" se trouve également dans le fichier "OWS.js". Il faut donc mettre à jour les 2 scripts. A+, Antoine Seiter

Page 1/1
   
Connexion
  • Accueil
  • Plan du site
  • Contact
Bewise TV, Blog technique, Webcasts...

Votre carrière et nous

  • Nos offres
  • Votre candidature
Ignorer les liens de navigation > Accueil > Nos Métiers > Portail et Travail Collaboratif > Détail Article
Ignorer les liens de navigation
Nous
Nos Métiers
Vous Former
Nos Evènements
Nos Références
Nos Activités
Nos Certifications
Nos Chiffres
Le Groupe
Nos Partenaires
On Parle de Nous
Nous contacter
Votre Carrière et Nous
Défiler vers le haut
Défiler vers le bas
Administration, Système et Communication
Architecture, Méthodes, Industrialisation
Décisionnel et Gestion des Données
Nouvelles Interfaces Utilisateurs
Portail et Travail Collaboratif
Solutions Langages et Framework
Solutions Web Avancées
Défiler vers le haut
Défiler vers le bas
Nos cours
Le Planning
Offres promotionnelles
Défiler vers le haut
Défiler vers le bas
Bewise Day Conference 2011
Nos Expresso
Défiler vers le haut
Défiler vers le bas
  • Infos légales
  • Lettre du Regional Director
  • Revue de presse