ASP.NET MVC, Web API & KnockoutJS

Renaud Dumont
Renaud DumontIT Evangelist / Developer / Networker en Microsoft Innovation Center Belgique / Pixels Festival / Mobile Dev Day / NTWRK
ASP.NET Web API: créer et
consommer un service REST
Si besoin, contactez-moi:

@DumontRenaud
renaud@mic-

belgique.be
-

ASP.NET MVC

-

Planning

Qu’est-ce qu’un service REST?

Le routing

-

CodeFirst : modèle de base de données

-

Web API ControllerSerialization JSON /
XML

-

Client Web avec Knockout
Qui suis-je ?
IT Evangelist au Microsoft Innovation Center
- Travaille avec la communauté sur le développement d’apps Windows Phone,
Windows 8, Kinect for Windows et Windows Azure
- Speaker régulier dans des conférences

Passionné de programmation, technologies et musique
- Participe à tous les évènements communautaires en Belgique et dans le
nord de la France
- Blogueur technique http://www.renauddumont.be
- Microsoft MVP Client Development depuis juillet 2013
Ou plutôt « REST-like ». On

REST

garde le bon pour se simplifier
la vie.
REST: qu’est-ce que c’est?
Representational State Transfer
REST est un style d’architecture dans lequel un client peut communiquer avec un serveur pour obtenir des
informations sur des données. REST un indépendant de tout protocole (moyen de communication).
Chaque donnée (objet) est identifiable par un URI (Unique Resource Identifier). REST utilise la notion d’hypermedia.
La communication entre le client et le serveur est dite Stateless. C’est-à-dire que chaque requête doit contenir
toutes les informations nécessaires pour pouvoir être traitée indépendamment des autres.
Le format des données reçues par le client est indépendant de celui utilisé pour le stockage des données.
Format de données indépendant
Je suis Renaud Dumont (abonné n° 45334)
Je veux le livre ISBN 282240142X au format Papier
Voici le livre « Développez en
HTML 5 pour Windows 8 »,
co-écrit par Loic Bar, Simon
Boigelot et Renaud Dumont

Je suis l’abonné n° 45334
Je veux le livre ISBN 282240142X
au format Ebook
Voici le livre numérique
« Développez en HTML 5
pour Windows 8 », co-écrit
par Loic Bar, Simon Boigelot
et Renaud Dumont
Des requêtes Stateless
Je suis Renaud Dumont (abonné n° 45334)
Je veux le livre ISBN 282240142X au format Papier
Voici le livre « Développez en
HTML 5 pour Windows 8 »,
co-écrit par Loic Bar, Simon
Boigelot et Renaud Dumont
Pourrais-je également avoir le livre ISBN
2092508261 au format Papier?
Bonjour, qui êtes-vous?
Ensemble de données reliées par des liens
hypermédia
Je suis Renaud Dumont (abonné n° 45334)
Je veux le livre ISBN 282240142X au format Papier
Voici le livre « Développez en
HTML 5 pour Windows
8 », co-écrit par Loic Bar
(AF3DS3), Simon Boigelot
(A54DF3), …
Je suis Renaud Dumont (abonné n° 45334)
Pourrais-je avoir la fiche de l’auteur Loic Bar (AF3DS3)?

Loïc Bar est un entrepreneur de 25 ans travaillant
dans le secteur ICT. Il a créé sa première boîte en
2008, juste après la fin de ses études et a travaillé
pour des références telles que McKinsey,
Microsoft, Coca-Cola, …
Protocole
HTTP

L’architecture REST se marie
plutôt bien avec HTTP.
Le protocole HTTP a toutes ces qualités (1/2)
Requête du client
-

Contacte une URL (URI)

-

Donne une information sur l’action à
effectuer (GET)

-

Donne les paramètres nécessaires à
l’identification (par cookies, ou dans le

header)
-

Indique le type de format attendu
Le protocole HTTP a toutes ces qualités (2/2)
Réponse du serveur
-

Renvoie l’état de la réponse (200 OK)

-

Le contenu de la réponse (body): une
page HTML

-

Donne des informations relatives au type
de contenu (text/html, utf-8)

-

Informations relatives aux politiques de
caching (no-cache)
ASP.NET MVC

Un bon début, mais peut mieux
faire.
Modèle – Vue – Contrôleur

User input
Requête http

Contrôleur

Modifier
l’état

Fournir des
données

Récupérer
l’état

Modèle

Vue

Output
HTML, …
Le Contrôleur
-

Chaque contrôleur définit des
actions

-

Une Action répond à une requête de
l’utilisateur en composant une
réponse

-

L’action peut éventuellement
modifier des données du modèle ou
en récupérer l’état
La vue
-

La Vue est un mélange de code HTML
et de C#.

-

Le View Engine Razor est utilisé pour
générer de véritables pages HTML à
partir des Vues.

-

La vue est responsable de l’affichage du
modèle et de la création d’interfaces
avec laquelle l’utilisateur peut interagir.
Le Modèle
-

Le modèle par défaut se compose d’une
classe UserProfile extensible pour la
gestion des profils utilisateurs.

-

Une classe héritant de DbContext
représente notre connexion avec la
base de données.

-

Le DbContext définit des DbSet<T>
correspondant à des tables de la base de
données.
Le template ASP.NET MVC 4 / Internet Application

Site web basique avec système
d’identification et d’autorisation.
Coup d’œil.
Code First

Partir du template de base et
puis tout casser.
Créer sa propre application
Application de gestion de tâches, Trello-like
Mettre de l’ordre

On est pas obligés d’aimer les
templates.
Gestion des TodoItem
- Créer une classe TodoItem ( Text, CreatedAt, Author, AssignedTo, ? )
en utilisant des conventions de nommage
- Ajouter un DbSet au DbContext pour représenter une table
- Scaffolding du Contrôleur et des Vues
- Test de l’application et observation de la table créée
Modification du modèle (1)
- AuthorId et AssignedToId sont requis par défaut : un entier n’est pas
nullable. Changement du type en int?
- Text doit être requis : annotation
- CreatedAt: utilisation de jQueryUI
- Et puis… forçons l’identification, et gérons ce qui ne dépend pas de
l’utilisateur côté serveur. Utilisation du helper HiddenFor(…)
Contexte modifié?
-

Lors de la première initialisation du
projet, la base de donnée est créé en
fonction des classes.

-

Si on modifie ces classes, le Context
n’est plus en phase avec la base de
données. Une exception est levée.

-

Utiliser un DatabaseInitializer (pratique
lors du développement) ou effectuer
une migration.
Premier client

Pourquoi ne peut-on pas
s’arrêter là?
Scénario courant
Un développeur que je ne connais pas veut créer une application
tierce pour les utilisateurs de mon site web.
You can't parse [X]HTML with regex.
http://bit.ly/parsehtml
Rappelez-vous REST
Une même ressource accessible dans différents formats,
indépendamment de se représentation.
Web API,
Bonjour!

Un service à la carte
API Controller

Si vous avez compris les
Controllers, vous êtes prêt pour les
API Controller.
Quelques différences (1/3) : Routing
Les API Controllers utilisent des routes différentes, pour pouvoir les
distinguer des contrôleurs classiques.
La route par défaut ne définit pas d’Action.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Quelques différences (2/3) : le type de retour
Les API Controllers ne font appel à aucune Vue.
Ils renvoient des données brutes en guise de réponse, ou des objets de
type HttpResponseMessage.
// GET api/TodoItem
public IEnumerable<TodoItem> GetTodoItems()
{
return db.TodoItems.AsEnumerable();
}
Quelques différences (2/3) : utilisation des messages
HTTP
GET, POST, PUT, DELETE. Convention de nommage ou attributs.
// POST api/TodoItem
public HttpResponseMessage PostTodoItem(TodoItem todoitem)
{
if (ModelState.IsValid)
{
db.TodoItems.Add(todoitem);
db.SaveChanges();
// do something
}
else
{
// do something else

}
}
Client Web

JavaScript, HTML, MVVM et
KnockoutJS
Une page all-in-one
- Mettre à jour les librairies de base: jQuery, jQueryUI, Modernizr, KnockoutJS
- Utilisation de Twitter Bootstrap (…, ou Foundation, ou ce que vous voulez. Mais ne
perdons pas de temps)
- Création d’un TodoList Controller

- Ajout d’une page Index
- Référencement des scripts nécéssaires: KnockoutJS et notre code perso.
Model-View-ViewModel
Notifications

Model

ViewModel

Business logic and
data

Presentation Logic

DataBinding
Commands

View
UI & UI Logic

On doit pouvoir imaginer le contenu de
l’interface en observant le ViewModel
Mon premier binding avec Knockout

Index.html
henallux.main.js
@{
ViewBag.Title = "Index";
}

var Henallux = {
viewModel: function () {
var __this = this;
__this.appTitle = ko.observable("Ma Super TodoList");
},

<h2 data-bind="text: appTitle"></h2>
@section scripts{
@Scripts.Render("~/bundles/knockoutjs")
@Scripts.Render("~/bundles/main")
}
};

initialize: function () {
var viewModel = new Henallux.viewModel();
ko.applyBindings(viewModel);
}

Henallux.initialize();
Lecture

HTTP GET : /api/TodoItem
Consommer l’API (1/4) : récupération des données
Pour pouvoir effectuer des requêtes sur notre API directement en
JavaScript, nous allons utiliser les requêtes AJAX avec jQuery
On entre dans le Web 2.0
Les requêtes AJAX permettent de faire du développement asynchrone ( !=
parallèle) avec l’utilisation des Promise.
JavaScript supporte nativement le JSON (JavaScript Object Notation)
Consommer l’API (1/4) : récupération des données
Les ObservableArray permettent
de définir des tableaux qui

seront observés en permanence
et notifieront l’interface de tout
changement.
KnockoutJS permet de binder
une collection à l’aide du motclé foreach en utilisant un
template définit en HTML.

henallux.main.js
__this.todoItems = ko.observableArray([]);
__this.loadData = function () {
$.ajax('http://localhost:1980/api/todoitem')
.then(function (items) {
for (var i in items) {
__this.todoItems.push(items[i]);
}
});
}

Index.html
<div data-bind="template: { name: 'todoitem-template', foreach: todoItems }"></div>

<script type="text/html" id="todoitem-template">
<div class="todoitem">
<h3><span style="font-style: italic;">Created by </span><span databind="text: Author.Username"></span></h3>
<p data-bind="text: Text"></p>
<p>Created at: <span data-bind="text: CreatedAt"></span></p>
</div>
</script>
Consommer l’API (1/4) : récupération des données
En théorie, une API REST utilise la notion d’hypermédia pour représenter les

associations entre objets.
Dans ce contexte-ci, on peut estimer qu’obtenir un TodoItem seul, sans

UserProfile n’a aucun sens et l’inclure d’office dans votre réponse.

Au risque de fâcher Roy T. Fielding…
Consommer l’API (1/4) : récupération des données
Possibilité de faire des jointures sur les tables en LinqToSql:
// GET api/TodoItem
public IEnumerable<TodoItem> GetTodoItems()
{
return db.TodoItems.Include("Author").AsEnumerable();
}
Suppression

HTTP DELETE :
/api/TodoItem/5
Consommer l’API (2/4) : suppression de données.
L’API.
L’action de suppression
d’un TodoItem s’attend à
recevoir un message
HTTP de type DELETE.
Il faut également fournir

en paramètre l’id de
l’élément à supprimer.

// DELETE api/TodoItem/5
public HttpResponseMessage DeleteTodoItem(int id)
{
TodoItem todoitem = db.TodoItems.Find(id);
if (todoitem == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.TodoItems.Remove(todoitem);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, todoitem);
}
Consommer l’API (2/4) : suppression de données.
L’AJAX.
Avec AJAX, il suffit de
préciser le type de
method comme étant
DELETE.

__this.deleteTodoItem = function (todoItem) {
var url = Henallux.serviceUrl + 'api/todoitem/' + todoItem.TodoItemId;
$.ajax(url, {
method: 'DELETE'
}).then(function (result) {
Henallux.viewModel.todoItems.remove(todoItem);
Henallux.viewModel.statusMessage("TodoItem supprimé.");
Henallux.viewModel.statusType("success");
}, function (error) {
Henallux.viewModel.statusMessage("Un erreur est survenue pendant l
a suppression de cet item.");
Henallux.viewModel.statusType("warning");
});
}
Consommer l’API (2/4) : suppression de données.
L’HTML.
KnockoutJS permet non seulement de binder des données,
mais également des fonctions sur des évènements. C’est le
principe des Commandes.
<script type="text/html" id="todoitem-template">
<div class="todoitem">

<span type="button" class="close" data-bind="click: $parent.deleteTodoItem" aria-hidden="true">&times;</span>
<h3><span style="font-style: italic;">Created by </span><span data-bind="text: Author.UserName"></span></h3>
<p data-bind="text: Text"></p>
<p>Created at: <span data-bind="text: CreatedAt"></span></p>
</div>
</script>
Insertion

HTTP POST: /api/TodoItem
Consommer l’API (3/4) : insertion de données.
L’API.
Le POST prend en

paramètre un objet de

// POST api/TodoItem

[Authorize]
public HttpResponseMessage PostTodoItem(TodoItem todoitem)
{
if (ModelState.IsValid)
{

var user = db.UserProfiles.FirstOrDefault(u => u.UserName == User.Identity.Name);
if (user == null)
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, “blablabla");

type TodoItem.

todoitem.AuthorId = user.UserId;
todoitem.CreatedAt = todoitem.ModifiedAt = DateTime.UtcNow;

Il faut envoyer ces

db.TodoItems.Add(todoitem);
db.SaveChanges();

données avec notre

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, todoitem);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = todoitem.TodoItemId }));
return response;

requête AJAX.

}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
Consommer l’API (3/4) : insertion de données.
HTML.
Quelques champs input vont permettre de récolter les données de l’utilisateur.

Un bouton pour déclencher la commande d’insertion.
<div>
<label>Texte</label>

<input type="text" id="new-todo-input-text" style="display: block;" />
</div>
<div>
<label>Assigné à... (Id)</label>

<input type="text" id="new-todo-input-assignedToId" style="display: block;" />
</div>

<button type="button" class="btn btn-primary" data-bind="click: insertTodoItem">Save changes</button>
Consommer l’API (3/4) : insertion de données.
JavaScript.
Récupération des valeurs dans les

__this.insertTodoItem = function () {
var text = $('#new-todo-input-text').val();
var assignedToId = $('#new-todo-input-assignedToId').val();

champs input.

if (!text) {
return;
}

Possibilité de validation client-side.

$.ajax(Henallux.serviceUrl + "api/todoitem", {
method: "POST",
data: JSON.stringify({
Text: text,
AssignedToId: assignedToId
}),
contentType: "application/json"
}).then(function (result) {
Henallux.viewModel.todoItems.push(result);

Utilisation de la méthode POST.
Envoi d’un objet au format JSON.

}, function (error) {
// handle error
});

Gestion de la réponse.
}
Modification

HTTP PUT: /api/TodoItem/5
Do it yourself
Analysez les APIs
1 de 51

Recomendados

ASP.NET from Zero to HeroASP.NET from Zero to Hero
ASP.NET from Zero to HeroCellenza
2.6K vistas16 diapositivas
ASP.NET MVC 5 et Web API 2ASP.NET MVC 5 et Web API 2
ASP.NET MVC 5 et Web API 2Microsoft
5K vistas29 diapositivas
ASP.NET MVC 6ASP.NET MVC 6
ASP.NET MVC 6Microsoft
4.2K vistas42 diapositivas
Soirée 3T Soat - Asp.net MVCSoirée 3T Soat - Asp.net MVC
Soirée 3T Soat - Asp.net MVCSOAT
2.2K vistas42 diapositivas
Introduction à ASP.NETIntroduction à ASP.NET
Introduction à ASP.NETAbdelouahed Abdou
7.7K vistas39 diapositivas

Más contenido relacionado

La actualidad más candente(20)

Destacado

NTWRK / #RDVPixel 06/13NTWRK / #RDVPixel 06/13
NTWRK / #RDVPixel 06/13Renaud Dumont
465 vistas13 diapositivas
Mobile Dev Day 2013Mobile Dev Day 2013
Mobile Dev Day 2013Renaud Dumont
666 vistas21 diapositivas
CafeNTournai #01CafeNTournai #01
CafeNTournai #01Renaud Dumont
478 vistas31 diapositivas
Be api - Web MobileBe api - Web Mobile
Be api - Web MobileNowhere-Entreprise
730 vistas41 diapositivas

Destacado(20)

NTWRK / #RDVPixel 06/13NTWRK / #RDVPixel 06/13
NTWRK / #RDVPixel 06/13
Renaud Dumont465 vistas
Mobile Dev Day 2013Mobile Dev Day 2013
Mobile Dev Day 2013
Renaud Dumont666 vistas
CafeNTournai #01CafeNTournai #01
CafeNTournai #01
Renaud Dumont478 vistas
Be api - Web MobileBe api - Web Mobile
Be api - Web Mobile
Nowhere-Entreprise730 vistas
Mobile Inception - Web API SecurityMobile Inception - Web API Security
Mobile Inception - Web API Security
MobileInception1.4K vistas
Backbonejs presentationBackbonejs presentation
Backbonejs presentation
Nicolas Vandenbogaerde809 vistas
Web APIs in Action (in French)Web APIs in Action (in French)
Web APIs in Action (in French)
Restlet2.1K vistas
Web API with ASP.NET  MVC  by Software development company in indiaWeb API with ASP.NET  MVC  by Software development company in india
Web API with ASP.NET MVC by Software development company in india
iFour Institute - Sustainable Learning537 vistas
TecknologisticTecknologistic
Tecknologistic
Heriberto Juan Linares Huapalla234 vistas
PentominiumPentominium
Pentominium
victorruizperez94218 vistas
Dépistage de l’anévrisme de l’aorte lilleDépistage de l’anévrisme de l’aorte lille
Dépistage de l’anévrisme de l’aorte lille
ARMVOP Médecin Vasculaire1.4K vistas

Similar a ASP.NET MVC, Web API & KnockoutJS(20)

Chapter1Chapter1
Chapter1
Brahim Bensbaa429 vistas
BreizhCamp - Drupal7 dans le cloud avec AzureBreizhCamp - Drupal7 dans le cloud avec Azure
BreizhCamp - Drupal7 dans le cloud avec Azure
Nicolas Georgeault1.9K vistas
Présentation de Django @ Orange Labs (FR)Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)
Martin Latrille1.6K vistas
CV_Bilel CHAOUADICV_Bilel CHAOUADI
CV_Bilel CHAOUADI
Bilel Chaouadi426 vistas
[Tuto] Big datatrack : Web Tracker[Tuto] Big datatrack : Web Tracker
[Tuto] Big datatrack : Web Tracker
Microsoft Technet France1K vistas
Support cours angularSupport cours angular
Support cours angular
Nizar MAATOUG -ISET Sidi Bouzid2K vistas
La plateforme Web MicrosoftLa plateforme Web Microsoft
La plateforme Web Microsoft
Christophe Lauer858 vistas
Introduction au développement AndroidIntroduction au développement Android
Introduction au développement Android
Steve Tremblay2.1K vistas
Glossaire web pour les profanes - WebdesignGlossaire web pour les profanes - Webdesign
Glossaire web pour les profanes - Webdesign
Relax In The Air1.7K vistas
Le Developpement Web Aspnet2   Vb2005Le Developpement Web Aspnet2   Vb2005
Le Developpement Web Aspnet2 Vb2005
Gregory Renard495 vistas
Linq et Entity frameworkLinq et Entity framework
Linq et Entity framework
DNG Consulting3.2K vistas
7_SitesWebMVC.pdf7_SitesWebMVC.pdf
7_SitesWebMVC.pdf
BerrySeven4 vistas

ASP.NET MVC, Web API & KnockoutJS

  • 1. ASP.NET Web API: créer et consommer un service REST Si besoin, contactez-moi: @DumontRenaud renaud@mic- belgique.be
  • 2. - ASP.NET MVC - Planning Qu’est-ce qu’un service REST? Le routing - CodeFirst : modèle de base de données - Web API ControllerSerialization JSON / XML - Client Web avec Knockout
  • 3. Qui suis-je ? IT Evangelist au Microsoft Innovation Center - Travaille avec la communauté sur le développement d’apps Windows Phone, Windows 8, Kinect for Windows et Windows Azure - Speaker régulier dans des conférences Passionné de programmation, technologies et musique - Participe à tous les évènements communautaires en Belgique et dans le nord de la France - Blogueur technique http://www.renauddumont.be - Microsoft MVP Client Development depuis juillet 2013
  • 4. Ou plutôt « REST-like ». On REST garde le bon pour se simplifier la vie.
  • 5. REST: qu’est-ce que c’est? Representational State Transfer REST est un style d’architecture dans lequel un client peut communiquer avec un serveur pour obtenir des informations sur des données. REST un indépendant de tout protocole (moyen de communication). Chaque donnée (objet) est identifiable par un URI (Unique Resource Identifier). REST utilise la notion d’hypermedia. La communication entre le client et le serveur est dite Stateless. C’est-à-dire que chaque requête doit contenir toutes les informations nécessaires pour pouvoir être traitée indépendamment des autres. Le format des données reçues par le client est indépendant de celui utilisé pour le stockage des données.
  • 6. Format de données indépendant Je suis Renaud Dumont (abonné n° 45334) Je veux le livre ISBN 282240142X au format Papier Voici le livre « Développez en HTML 5 pour Windows 8 », co-écrit par Loic Bar, Simon Boigelot et Renaud Dumont Je suis l’abonné n° 45334 Je veux le livre ISBN 282240142X au format Ebook Voici le livre numérique « Développez en HTML 5 pour Windows 8 », co-écrit par Loic Bar, Simon Boigelot et Renaud Dumont
  • 7. Des requêtes Stateless Je suis Renaud Dumont (abonné n° 45334) Je veux le livre ISBN 282240142X au format Papier Voici le livre « Développez en HTML 5 pour Windows 8 », co-écrit par Loic Bar, Simon Boigelot et Renaud Dumont Pourrais-je également avoir le livre ISBN 2092508261 au format Papier? Bonjour, qui êtes-vous?
  • 8. Ensemble de données reliées par des liens hypermédia Je suis Renaud Dumont (abonné n° 45334) Je veux le livre ISBN 282240142X au format Papier Voici le livre « Développez en HTML 5 pour Windows 8 », co-écrit par Loic Bar (AF3DS3), Simon Boigelot (A54DF3), … Je suis Renaud Dumont (abonné n° 45334) Pourrais-je avoir la fiche de l’auteur Loic Bar (AF3DS3)? Loïc Bar est un entrepreneur de 25 ans travaillant dans le secteur ICT. Il a créé sa première boîte en 2008, juste après la fin de ses études et a travaillé pour des références telles que McKinsey, Microsoft, Coca-Cola, …
  • 9. Protocole HTTP L’architecture REST se marie plutôt bien avec HTTP.
  • 10. Le protocole HTTP a toutes ces qualités (1/2) Requête du client - Contacte une URL (URI) - Donne une information sur l’action à effectuer (GET) - Donne les paramètres nécessaires à l’identification (par cookies, ou dans le header) - Indique le type de format attendu
  • 11. Le protocole HTTP a toutes ces qualités (2/2) Réponse du serveur - Renvoie l’état de la réponse (200 OK) - Le contenu de la réponse (body): une page HTML - Donne des informations relatives au type de contenu (text/html, utf-8) - Informations relatives aux politiques de caching (no-cache)
  • 12. ASP.NET MVC Un bon début, mais peut mieux faire.
  • 13. Modèle – Vue – Contrôleur User input Requête http Contrôleur Modifier l’état Fournir des données Récupérer l’état Modèle Vue Output HTML, …
  • 14. Le Contrôleur - Chaque contrôleur définit des actions - Une Action répond à une requête de l’utilisateur en composant une réponse - L’action peut éventuellement modifier des données du modèle ou en récupérer l’état
  • 15. La vue - La Vue est un mélange de code HTML et de C#. - Le View Engine Razor est utilisé pour générer de véritables pages HTML à partir des Vues. - La vue est responsable de l’affichage du modèle et de la création d’interfaces avec laquelle l’utilisateur peut interagir.
  • 16. Le Modèle - Le modèle par défaut se compose d’une classe UserProfile extensible pour la gestion des profils utilisateurs. - Une classe héritant de DbContext représente notre connexion avec la base de données. - Le DbContext définit des DbSet<T> correspondant à des tables de la base de données.
  • 17. Le template ASP.NET MVC 4 / Internet Application Site web basique avec système d’identification et d’autorisation. Coup d’œil.
  • 18. Code First Partir du template de base et puis tout casser.
  • 19. Créer sa propre application Application de gestion de tâches, Trello-like
  • 20. Mettre de l’ordre On est pas obligés d’aimer les templates.
  • 21. Gestion des TodoItem - Créer une classe TodoItem ( Text, CreatedAt, Author, AssignedTo, ? ) en utilisant des conventions de nommage - Ajouter un DbSet au DbContext pour représenter une table - Scaffolding du Contrôleur et des Vues - Test de l’application et observation de la table créée
  • 22. Modification du modèle (1) - AuthorId et AssignedToId sont requis par défaut : un entier n’est pas nullable. Changement du type en int? - Text doit être requis : annotation - CreatedAt: utilisation de jQueryUI - Et puis… forçons l’identification, et gérons ce qui ne dépend pas de l’utilisateur côté serveur. Utilisation du helper HiddenFor(…)
  • 23. Contexte modifié? - Lors de la première initialisation du projet, la base de donnée est créé en fonction des classes. - Si on modifie ces classes, le Context n’est plus en phase avec la base de données. Une exception est levée. - Utiliser un DatabaseInitializer (pratique lors du développement) ou effectuer une migration.
  • 24. Premier client Pourquoi ne peut-on pas s’arrêter là?
  • 25. Scénario courant Un développeur que je ne connais pas veut créer une application tierce pour les utilisateurs de mon site web.
  • 26. You can't parse [X]HTML with regex. http://bit.ly/parsehtml
  • 27. Rappelez-vous REST Une même ressource accessible dans différents formats, indépendamment de se représentation.
  • 29. API Controller Si vous avez compris les Controllers, vous êtes prêt pour les API Controller.
  • 30. Quelques différences (1/3) : Routing Les API Controllers utilisent des routes différentes, pour pouvoir les distinguer des contrôleurs classiques. La route par défaut ne définit pas d’Action. config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
  • 31. Quelques différences (2/3) : le type de retour Les API Controllers ne font appel à aucune Vue. Ils renvoient des données brutes en guise de réponse, ou des objets de type HttpResponseMessage. // GET api/TodoItem public IEnumerable<TodoItem> GetTodoItems() { return db.TodoItems.AsEnumerable(); }
  • 32. Quelques différences (2/3) : utilisation des messages HTTP GET, POST, PUT, DELETE. Convention de nommage ou attributs. // POST api/TodoItem public HttpResponseMessage PostTodoItem(TodoItem todoitem) { if (ModelState.IsValid) { db.TodoItems.Add(todoitem); db.SaveChanges(); // do something } else { // do something else } }
  • 33. Client Web JavaScript, HTML, MVVM et KnockoutJS
  • 34. Une page all-in-one - Mettre à jour les librairies de base: jQuery, jQueryUI, Modernizr, KnockoutJS - Utilisation de Twitter Bootstrap (…, ou Foundation, ou ce que vous voulez. Mais ne perdons pas de temps) - Création d’un TodoList Controller - Ajout d’une page Index - Référencement des scripts nécéssaires: KnockoutJS et notre code perso.
  • 35. Model-View-ViewModel Notifications Model ViewModel Business logic and data Presentation Logic DataBinding Commands View UI & UI Logic On doit pouvoir imaginer le contenu de l’interface en observant le ViewModel
  • 36. Mon premier binding avec Knockout Index.html henallux.main.js @{ ViewBag.Title = "Index"; } var Henallux = { viewModel: function () { var __this = this; __this.appTitle = ko.observable("Ma Super TodoList"); }, <h2 data-bind="text: appTitle"></h2> @section scripts{ @Scripts.Render("~/bundles/knockoutjs") @Scripts.Render("~/bundles/main") } }; initialize: function () { var viewModel = new Henallux.viewModel(); ko.applyBindings(viewModel); } Henallux.initialize();
  • 37. Lecture HTTP GET : /api/TodoItem
  • 38. Consommer l’API (1/4) : récupération des données Pour pouvoir effectuer des requêtes sur notre API directement en JavaScript, nous allons utiliser les requêtes AJAX avec jQuery On entre dans le Web 2.0 Les requêtes AJAX permettent de faire du développement asynchrone ( != parallèle) avec l’utilisation des Promise. JavaScript supporte nativement le JSON (JavaScript Object Notation)
  • 39. Consommer l’API (1/4) : récupération des données Les ObservableArray permettent de définir des tableaux qui seront observés en permanence et notifieront l’interface de tout changement. KnockoutJS permet de binder une collection à l’aide du motclé foreach en utilisant un template définit en HTML. henallux.main.js __this.todoItems = ko.observableArray([]); __this.loadData = function () { $.ajax('http://localhost:1980/api/todoitem') .then(function (items) { for (var i in items) { __this.todoItems.push(items[i]); } }); } Index.html <div data-bind="template: { name: 'todoitem-template', foreach: todoItems }"></div> <script type="text/html" id="todoitem-template"> <div class="todoitem"> <h3><span style="font-style: italic;">Created by </span><span databind="text: Author.Username"></span></h3> <p data-bind="text: Text"></p> <p>Created at: <span data-bind="text: CreatedAt"></span></p> </div> </script>
  • 40. Consommer l’API (1/4) : récupération des données En théorie, une API REST utilise la notion d’hypermédia pour représenter les associations entre objets. Dans ce contexte-ci, on peut estimer qu’obtenir un TodoItem seul, sans UserProfile n’a aucun sens et l’inclure d’office dans votre réponse. Au risque de fâcher Roy T. Fielding…
  • 41. Consommer l’API (1/4) : récupération des données Possibilité de faire des jointures sur les tables en LinqToSql: // GET api/TodoItem public IEnumerable<TodoItem> GetTodoItems() { return db.TodoItems.Include("Author").AsEnumerable(); }
  • 43. Consommer l’API (2/4) : suppression de données. L’API. L’action de suppression d’un TodoItem s’attend à recevoir un message HTTP de type DELETE. Il faut également fournir en paramètre l’id de l’élément à supprimer. // DELETE api/TodoItem/5 public HttpResponseMessage DeleteTodoItem(int id) { TodoItem todoitem = db.TodoItems.Find(id); if (todoitem == null) { return Request.CreateResponse(HttpStatusCode.NotFound); } db.TodoItems.Remove(todoitem); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex); } return Request.CreateResponse(HttpStatusCode.OK, todoitem); }
  • 44. Consommer l’API (2/4) : suppression de données. L’AJAX. Avec AJAX, il suffit de préciser le type de method comme étant DELETE. __this.deleteTodoItem = function (todoItem) { var url = Henallux.serviceUrl + 'api/todoitem/' + todoItem.TodoItemId; $.ajax(url, { method: 'DELETE' }).then(function (result) { Henallux.viewModel.todoItems.remove(todoItem); Henallux.viewModel.statusMessage("TodoItem supprimé."); Henallux.viewModel.statusType("success"); }, function (error) { Henallux.viewModel.statusMessage("Un erreur est survenue pendant l a suppression de cet item."); Henallux.viewModel.statusType("warning"); }); }
  • 45. Consommer l’API (2/4) : suppression de données. L’HTML. KnockoutJS permet non seulement de binder des données, mais également des fonctions sur des évènements. C’est le principe des Commandes. <script type="text/html" id="todoitem-template"> <div class="todoitem"> <span type="button" class="close" data-bind="click: $parent.deleteTodoItem" aria-hidden="true">&times;</span> <h3><span style="font-style: italic;">Created by </span><span data-bind="text: Author.UserName"></span></h3> <p data-bind="text: Text"></p> <p>Created at: <span data-bind="text: CreatedAt"></span></p> </div> </script>
  • 47. Consommer l’API (3/4) : insertion de données. L’API. Le POST prend en paramètre un objet de // POST api/TodoItem [Authorize] public HttpResponseMessage PostTodoItem(TodoItem todoitem) { if (ModelState.IsValid) { var user = db.UserProfiles.FirstOrDefault(u => u.UserName == User.Identity.Name); if (user == null) return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, “blablabla"); type TodoItem. todoitem.AuthorId = user.UserId; todoitem.CreatedAt = todoitem.ModifiedAt = DateTime.UtcNow; Il faut envoyer ces db.TodoItems.Add(todoitem); db.SaveChanges(); données avec notre HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, todoitem); response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = todoitem.TodoItemId })); return response; requête AJAX. } else { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } }
  • 48. Consommer l’API (3/4) : insertion de données. HTML. Quelques champs input vont permettre de récolter les données de l’utilisateur. Un bouton pour déclencher la commande d’insertion. <div> <label>Texte</label> <input type="text" id="new-todo-input-text" style="display: block;" /> </div> <div> <label>Assigné à... (Id)</label> <input type="text" id="new-todo-input-assignedToId" style="display: block;" /> </div> <button type="button" class="btn btn-primary" data-bind="click: insertTodoItem">Save changes</button>
  • 49. Consommer l’API (3/4) : insertion de données. JavaScript. Récupération des valeurs dans les __this.insertTodoItem = function () { var text = $('#new-todo-input-text').val(); var assignedToId = $('#new-todo-input-assignedToId').val(); champs input. if (!text) { return; } Possibilité de validation client-side. $.ajax(Henallux.serviceUrl + "api/todoitem", { method: "POST", data: JSON.stringify({ Text: text, AssignedToId: assignedToId }), contentType: "application/json" }).then(function (result) { Henallux.viewModel.todoItems.push(result); Utilisation de la méthode POST. Envoi d’un objet au format JSON. }, function (error) { // handle error }); Gestion de la réponse. }

Notas del editor

  1. N’utiliser que les AuthorId ici. On ajoutera les foreign key après.