L’objectif de ce tutoriel (associé au module 7) est de montrer comment intégrer les technologies AJAX dans les applications ASP.NET. La première partie, utilise les dates pour montrer comment UpdatePanel permet uniquement à des portions de page d’être actualisées. La deuxième partie consiste en la création d’un service web et son invocation depuis le client en utilisant JavaScript et JQuery.
Prérequis : Ce tutoriel requiert que la base de données « AdventureWorks » soit installée dans la machine. Cette base peut être téléchargée sur http://sqlserversamples.codeplex.com/ .
Etape 1 – Préparation
L’objectif de cette étape est de préparer l’application.
- Créer une nouvelle application ASP.NET vide appelée « TestAJAX »
- Créez trois pages dans la nouvelle application « Default.aspx », « Partiel.aspx » et « Service.aspx »
- Dans la page web « Default.aspx » ajoutez deux liens pointant respectivement sur « Partiel.aspx » et « Service.aspx » avec la propriété « Text » égale à : « Chargement Partiel » et « Service Web » respectivement.
- Ajoutez un modèle EntityFramework appelé « AdventureModel » pointant sur la base de données « AdventureWorks ». Le nom du contexte doit être « AdventureContext ». Pour plus de détails voir « Module 6 ». N’oubliez pas de cochez « Mettre au plusieurs ou au singulier les entités générées ». Le modèle inclut une seule table « Product » et génère une seule entité « Product »
- Ajoutez une feuille de style appelée « Site.css »
- Ajoutez les règles suivantes à la feuille de style :
body {
font-family: 'Gill Sans' , 'Gill Sans MT' , Calibri, 'Trebuchet MS' , sans-serif;
}
.asideBar {
border: thin solid #919191;
float: left;
margin: 5px;
background-color: #F8E9AD;
padding : 5px;
min-width : 200px;
min-height : 400px;
}
div.content {
border: thin solid #0D86FF;
float: left;
margin: 5px;
padding: 5px;
}
div.clear {
float : left;
}
.loading {
text-align: center;
background-color: #C24B4B;
color: #FFFFFF;
margin-top: 2px;
padding: 3px;
}
- Ouvrez la page « Partiel.aspx » en mode source
- Insérez les balises suivantes après la balise « div » du formulaire (« form ») :
<div>
<aside class="asideBar">
</aside>
<div class="content">
</div>
<div class="clear" />
</div>
- Ouvrez la page « Partiel.aspx » en mode design
- Faites glisser le fichier « Site.css » sur la page afin d’appliquer le style.
- Ouvrez la console du gestionnaire de paquets « Nuget »
- Installez « JQuery » en entrant « Install-Package JQuery »
Etape 2 : Implémentation de chargement partiel
L’objectif de cette étape de permettre au développeur de voir l’effet du chargement partiel en comparant entre le contenu de deux libellés. Elle montre aussi l’utilisation de l’UpdatePanel en conjonction avec l’UpdateProgress.
- Ouvrez la page « Partiel.aspx » en mode design
- Cliquez sur la barre latérale « aside » puis insérer un « Label » dedans
- A partir de la barre à outils, ajoutez un « ScriptManager » (onglet extensions AJAX) en début de page
- Ajoutez une source de données « EntityDataSource » et pointez-la sur l’ensemble « Products » du contexte « AdventureContext ». Si vous n’arrivez pas à voir le contexte, compilez la solution en appuyant sur « F6 »
- Ajoutez un « UpdatePanel » dans la « div » dont la classe est « content »
- Insérez un deuxième « Label » à l’intérieur de l’UpdatePanel que vous venez d’ajouter
- Ajoutez un « GridView » à l’intérieur du composant « UpdatePanel » que vous venez d’ajouter. Configurez la source de données pour pointer sur la source de données « EntityDataSource » ajoutée précédemment.
- Configurez le « GridView » de façon à ce qu’il ne contienne que les colonnes « ProductID », « Name » et « Color »
- Configurez la pagination du GridView en affectant « True » à la propriété « AllowPaging »
- Ajoutez un composant « UpdateProgress » en dessous du « UpdatePanel »
- Dans la propriété « DisplayAfter », entrez 50
- Dans la propriété « AssociatedUpdatepanelID » entrez « UpdatePanel1 »
- Affichez la page « Partiel.aspx » en mode source
- Dans la propriété « ProgressTemplate » de l’UpdateProgress insérez un div et du texte comme suit :
<asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="50" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<div class="loading">Chargement en cours...</div>
</ProgressTemplate>
</asp:UpdateProgress>
- La page en mode design doit être comme suit :
- Le code ASPX généré doit être comme celui-ci :
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:EntityDataSource ID="EntityDataSource1" runat="server" ConnectionString="name=AdventureContext" DefaultContainerName="AdventureContext" EnableFlattening="False" EntitySetName="Products">
</asp:EntityDataSource>
<aside class="asideBar">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</aside>
<div class="content">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
<br />
<asp:GridView ID="GridView1" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AllowPaging="True" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="EntityDataSource1">
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Color" HeaderText="Color" SortExpression="Color" />
</Columns>
<FooterStyle BackColor="Tan" />
<HeaderStyle BackColor="Tan" Font-Bold="True" />
<PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
<SortedAscendingCellStyle BackColor="#FAFAE7" />
<SortedAscendingHeaderStyle BackColor="#DAC09E" />
<SortedDescendingCellStyle BackColor="#E1DB9C" />
<SortedDescendingHeaderStyle BackColor="#C2A47B" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="50" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<div class="loading">Chargement en cours...</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
<div class="clear" />
</div>
</form>
- Passez en mode « Code Behind » en appuyant sur « F7 »
- Dans la méthode « Page_Load », affectez la date en cours aux deux libellés comme suit :
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
Label2.Text = DateTime.Now.ToString();
}
- Exécutez en appuyant sur « F5 » et naviguez jusqu’à la page « Partiel.aspx »
- Remarquez qu’en changeant la page en cours dans la grille, la date ne change que pour un seul libellé alors que la page devait changer les deux
- Remarquez que le « UpdateProgress » s’affiche à chaque fois qu’un lien de pagination est cliqué
Etape 3 : Création d’un service web WCF
- Dans le projet « TestAJAX », cliquez sur « Ajouter un Nouvel Elément »
- Dans le modèle sélectionnez « Service WCF AJAX »
- Dans la zone « Nom », entrez « ProductService »
- Appuyez sur « OK »
- Remarquez que VS génère une classe de service avec une seule méthode « DoWork » comme suit :
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ProductService
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
public void DoWork()
{
// Add your operation implementation here
return;
}
// Add more operations here and mark them with [OperationContract]
}
- Supprimez la méthode « DoWork » de la classe
- Ajoutez une méthode « GetProduct » décorée par l’attribut « OperationContract »
- L’attribut « OperationContract » stipule que la méthode peut être appelée comme service
- Changez le code de la méthode comme suit :
[OperationContract]
public Product GetProduct(int id)
{
using (var context = new AdventureContext())
{
return context.Products.FirstOrDefault(e => e.ProductID == id);
}
}
- Compilez en appuyant sur « F6 » et vérifiez qu’il n’y a pas d’erreur
- Ouvrez la page « Default.aspx »
- Exécutez en appuyant sur « F5 »
- Dans la barre d’adresse du navigateur, remplacez « Default.aspx » par « ProductService.svc »
- Remarquez les informations données sur le service permettant aux clients de l’invoquer.
Etape 4 : Invocation du service web depuis JavaScript
Le but de cette étape est d’utiliser le composant « ScriptManager » afin qu’il génère les proxies nécessaires à l’invocation du service « ProductService ». Pour invoquer le services, des évènements JQuery seront utilisés.
- Ouvrez la page « Service.aspx » en mode design
- Glissez un « ScriptManager » sur la page
- Cliquez sur la propriété « Services » du « ScriptManager » puis sur le bouton en pointillés qui apparaît
- Cliquez sur le bouton « Ajouter »
- A droite, dans la propriété « Path », entrez « ~/ProductService.svc »
- Cliquez sur « OK »
- Ouvrez la page « Service.aspx » en mode source
- Ajoutez trois paragraphes (« <p> ») dont les deux derniers ont l’attribut « class » à « info »
- Dans le premier paragraphe, ajoutez une balise « label » contenant le texte « Numéro : »
- Dans le premier paragraphe, ajoutez un contrôle HTML (pas ASP.NET) de type bouton avec la propriété « ID » pour « btnChercher » et l’attribut « value » à « Trouver Produit »
- Dans le deuxième paragraphe, ajoutez une balise « label » avec le texte « Nom : »
- Dans le deuxième paragraphe, ajoutez un contrôle HTML « input (Text ») avec la propriété « ID » à « txtNom »
- Dans le troisième paragraphe ajoutez une balise « label » avec le texte « Couleur : »
- Dans le deuxième paragraphe, ajoutez un contrôle HTML « input (Text ») avec la propriété « ID » à « txtNom »
- Le code devra ressembler au code qui suit :
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/ProductService.svc" />
</Services>
</asp:ScriptManager>
<p>
<label>
Trouver :
<input id="txtNumero" type="text" /></label>
<input id="btnChercher" type="button" value="Trouver Produit" />
</p>
<p class="info">
<label>
Nom :
</label>
<input id="txtNom" type="text" />
</p>
<p class="info">
<label>
Couleur :
</label>
<input id="txtCouleur" type="text" />
</p>
</div>
- En mode source toujours, faites glisser le fichier « JQuey-x.y.z.js » dans la page juste avant la balise «/head » fermante où x.y.z est la version installée de JQuery
- En mode source, ajoutez le script « JavaScript » suivant :
<script type="text/javascript">
$(function () {
$(".info").hide();
$("#btnChercher").click(function () {
var numero = $("#txtNumero").val();
ProductService.GetProduct(numero, function (data) {
if (data == null) {
alert('non trouvé !');
$(".info").hide();
}
else {
$("#txtNom").val(data.Name);
$("#txtCouleur").val(data.Color);
$(".info").show();
}
});
});
});
</script>
- La ligne suivante permet d’invoquer l’opération « GetService » du service « GetProduct » avec comme paramètre la variable « numero ». Le deuxième paramètre est la fonction à appeler lorsque l’appel réussit. AJAX est bâti sur ce genre d’appel car le services s’exécutent d’une manière asynchrone, la fonction passée en paramètre est appelée « callback ».
ProductService.GetProduct(numero, function (data) {
if (data == null) {
alert('non trouvé !');
$(".info").hide();
}
else {
$("#txtNom").val(data.Name);
$("#txtCouleur").val(data.Color);
$(".info").show();
}
});
- Exécutez l’application en appuyant sur « F5 »
Pour télécharger le code du tutoriel, cliquez ici