[AJAX] Introduction à ASP.NET 4 (AJAX 4)
ASP.NET 4 est certainement l’une des technologies qui apporte le plus de nouveautés.
On y retrouve:
- MVC 2
- Webforms 4.0
- Intégration jQuery
- ASP.NET AJAX 4
- Amélioration de Dynamic Data
- …
Dans ce premier post sur ASP.NET 4, je me suis concentré sur ASP.NET AJAX 4 qui apporte pas mal de nouveautés comme le live databinding (un peu comme en WPF) ou encore les templates de rendu client.

La solution de ce post a été réalisée avec VS2010 B2 et téléchargeable ici.
Installation et téléchargement
Pour utiliser ASP.NET AJAX 4 il faut télécharger la dernière version (actuellement Preview 6) sur http://codeplex.com/aspnet
jQuery est quant à lui intégré de base dans votre projet ASP.NET Web Application depuis la béta 2 de Visual Studio 2010.
ASP.NET AJAX 4 supporte les navigateurs suivant:
· Microsoft Internet Explorer 6, 7, 8
· Mozilla Firefox 3, 3.5
· Apple Safari 4
· Opera 10
· Chrome 3
Pour utiliser ASP.NET AJAX vous pouvez utiliser le fichier Start.js qui chargera dynamiquement les scripts dont vous aurez besoin.
Pour débuguer les requêtes AJAX j’utiliserai dans ce billet Mozilla avec le plug in Firebug.
Utiliser ASP.NET AJAX Client Templates
Les Client Templates utilisent de l’AJAX pure, c’est à dire l’utilisation d’un service côté serveur qui va délivrer des données au format JSON et c’est le client qui s’occupera du rendu.
Jusqu’à présent nous utilisions l’updatepanel. Le problème de ce contrôle est que cela reste avant tout un postback et que cela engendre des traitements côté serveur et un échange entre le client et le serveur au format HTML (beaucoup plus lourd que le JSON surtout avec le ViewState). Le rendu n’étant pas généré par le client mais par le serveur.
Nous allons voir comment créer un formulaire nous permettant:
- D’afficher des clients
- De sélectionner des clients (avec la mise en œuvre du Live Bindings, Mode, converters..)
- De modifier/supprimer des clients
Etape 1 est de créer un service dans notre application ASP.NET capable d’envoyer des clients au format JSON.

Pour cela on utilise un service AJAX enabled qui active par défaut la sérialisation JSON.
Le DataContract est un simple type client:
[DataContract]
public class Client
{
[DataMember]
public string Nom { get; set; }
[DataMember]
public string Prenom { get; set; }
[DataMember]
public string Avatar { get; set; }
}
Le service contient une méthode GetClients:
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ClientsService
{
[OperationContract]
public Client[] GetClients()
{
string UrlAvatar = "Frankenstein.png";
return new[]
{
new Client(){Avatar = UrlAvatar, Prenom = "Julien", Nom = "Dollon"},
new Client(){Avatar = UrlAvatar, Prenom = "Julien2", Nom = "Dollon2"},
new Client(){Avatar = UrlAvatar, Prenom = "Julien3", Nom = "Dollon3"}
};
}
}
Pour l’affichage nous allons utiliser le Pure Ajax avec les clients templates. Par exemple si nous souhaitons afficher le nom des clients dans un UL:
<ul id="MyListView" class="sys-template">
<li>{{ Nom }}</li>
</ul>
Pour éviter qu’au chargement le {{ Nom }} apparaisse, il faut utiliser un style “sys-template” que nous définissons comme caché. C’est la librairie AJAX qui se chargera de le rendre visible une fois les données chargées.
<style>
.sys-template { visibility:hidden; display:none; }
</style>
A l’ouverture de la page, on charge les scripts dont on a besoin (içi DataView pour l’affichage et WebServices pour la communication avec WCF). Puis on instancie notre balise UL avec le type DataView:
<script type="text/javascript" src="Scripts/MicrosoftAjax/start.js"/>
<script type="text/javascript">
Sys.loader.debug = true;
//Chargement des scripts
Sys.require([Sys.components.dataView, Sys.scripts.WebServices]);
//Au chargement on instancie la dataView
Sys.onReady(function () {
Sys.create.dataView("#MyListView",
{
dataProvider: "ClientsService.svc",
fetchOperation: "GetClients",
autoFetch: "true"
}
);
});
</script>
A l’exécution tous les scripts se chargent et AJAX interroge le service:
Nous modifions le client template pour pouvoir afficher l’avatar et un lien de sélection. Pour information, si nous souhaitons utiliser le binding sur une propriété d’une balise (par exemple SRC de <Image/>) nous devons ajouter sys: devant:
<div id="MyListView" class="sys-template">
<div>
<img sys:src="{{ Avatar }}"/>
{{ Nom }}
</div>
</div>
sys est un namespace xml déclaré dans la balise body:
<body xmlns:sys="javascript:Sys">
Pour la sélection, nous allons faire appel à sys:command et utiliser du live binding pour remplir dans une textbox le prénom du client selectionné.
On crée un style pour le champ sélectionné:
.selectedRow { background-color: Blue; }
Puis on modifie le client template afin d’en avoir 2. L’un étant une simple textbox affichant le prénom du client:
<div>
<div id="MyListView" class="sys-template" >
<span sys:command="select">
<img sys:src="{{ Avatar }}"/>
{{ Nom }}
</span>
</div>
<div id="MyListViewDetail" class="sys-template">
<input type="text" sys:value="{binding Prenom}" />
</div>
Remarquez le sys:command qui déclenchera la sélection ainsi que le {binding Prenom} qui est une autre façon d’écrire le binding. Cette façon est plus complète car on peut y appliquer comme en WPF:
- Des converters
- un mode (oneway, twoway…)
Par exemple
<input type="text" value="{binding Prenom, convert=Method1, convertBack=Method2, mode=twoWay}"/>
Pour terminer on lie les deux dataviews à l’instanciation. On aurai pu également le faire directement dans le code HTML grâce à des balises contenues dans sys:.
<script type="text/javascript">
Sys.loader.debug = true;
//Chargement des scripts
Sys.require([Sys.components.dataView, Sys.scripts.WebServices]);
//Au chargement on instancie la dataView
Sys.onReady(function () {
var primary = Sys.create.dataView("#MyListView",
{
dataProvider: "ClientsService.svc",
fetchOperation: "GetClients",
autoFetch: "true",
selectedItemClass: "selectedRow",
initialSelectedIndex: 0
}
);
//On instancie la seconde dataview
var second = Sys.create.dataView("#MyListViewDetail");
//On met en place le binding
Sys.bind(second, "data", primary, "selectedData");
});
</script>
Le résultat est fonctionnel et très laid mais montre bien la puissance de ce nouveau type de développement:
Pour l’édition ou la suppression, la technique dépend si vous avez utilisé le DataContext (ce qui n’est pas le cas ici).
Vous pouvez créer des commandes comme Select et faire un traitement derrière.
<div id="MyListView" class="sys-template"
sys:attach="dataview"
dataview:oncommand="{{ onDetailViewCommand }}">
<span>
<a href="#" sys:command="Select"
sys:commandargument="{{$index}}">Select</a>
<a href="#" sys:command="Delete"
sys:commandargument="{binding Nom}">Delete</a>
<img sys:src="{{ Avatar }}"/>
{{ Nom }}
</span>
</div>
On précise la méthode javascript à appeler lors du déclenchement d’une commande (ici onDetailViewCommand).
function onDetailViewCommand(sender, args) {
switch (args.get_commandName()) {
case "Delete":
//Requête sur DataContext ou WCF
break;
case "Select":
primary.set_selectedIndex(args.get_commandArgument());
break;
}
Exploiter ADO.NET Data Services avec AJAX 4
Nous aurions pu aller chercher nos données dans un service Astoria. Référez vous à cet article pour plus d’informations.
Un peu de style… ou pas !
Cette étape ne sera pas expliquée, mais après une ligne de CSS, le résultat ressemble à ceci:

j’ai conscience que cela fait égocentrique mais c’était les seuls “vrai” avatar que j’avais sous la main.
Intégration avec jQuery
Depuis Visual Studio 2008 béta 2, jQuery est intégré de base (j’en parle ici).
Si MS AJAX est utilisé pour tout ce qui est AJAX, nous pouvons le compléter avec jQuery afin d’utiliser son sélecteur puissant, ses effets, ses librairies UI…
C’est ce que l’on va faire. Je souhaite que de base tous mes éléments soient transparent et sur le survol de la souris ils deviendront opaque.
<script src="Scripts/jQuery/jquery-1.3.2.js" type="text/javascript" />
<script type="text/javascript">
$(document).ready(function () {
$('img').fadeTo(0, 0.5);
$('img').live("mouseover", function () {
$(this).fadeTo(200, 1);
})
$('img').live("mouseout", function () {
$(this).fadeTo(200, 0.5);
})
;
});
</script>
J’aurais bien pu chainer ces lignes. L’utilisation de la méthode live() s’explique par le fait que des éléments sont ajoutés à la volé.
Résultat:

Voilà pour le moment ;)