Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
ACCEDER AUX DONNEES AVEC .NET, INTRODUCTION
Sommaire Introduction ............................................................................................................................................ 2
Les prérequis ........................................................................................................................................... 2
Matériel ................................................................................................................................................... 2
Un peu d’histoire : REST, SOAP ............................................................................................................... 3
Web Services / SOAP ........................................................................................................................... 3
REST ..................................................................................................................................................... 3
OData ...................................................................................................................................................... 4
WCF Data Service .................................................................................................................................... 6
Projet WCF Data Services / OData / REST ..................................................... Erreur ! Signet non défini.
Introduction Ce cours a pour but d’apprendre et comprendre les bases de l’accès aux données avec ADO.NET
Les prérequis Ce cours s’adresse à toutes les personnes désirant comprendre les mécanismes mis en jeu lors de
l’accès aux données.
Une connaissance de C# est conseillé pour bien appréhender tous les concepts.
Matériel Pour suivre ce tutorial, vous aurez besoin de :
1. Visual Studio 2013 / Express : Le cours est basé sur Visual Studio 2013 Ultimate, mais vous
pouvez utiliser Visual Studio Express : http://www.visualstudio.com/fr-fr
2. SQL Server 2014 / Express / LocalDB : La base de données sera hébergée sur un server SQL.
Vous pouvez utiliser la version SQL Server qui vous convient, SQL Server 2005 à 2014 ou SQL
Server Express / LocalDB pour les versions gratuites.
La version SQL Express est disponible ici : http://www.microsoft.com/fr-
fr/download/details.aspx?id=29062
3. Base de données Northwind : Cette base de données contient quelques données exemples.
Vous pouvez la télécharger ici : http://northwind.codeplex.com
4. Solutions du tutorial : L’ensemble des sources de ce cours sont disponibles directement en
tant que fichier joint de ce module
Un peu d’histoire : REST, SOAP Avant, la mode (oui tout est question de mode, de tendance, même en informatique) était aux
Web Services.
Aujourd’hui la mode c’est plutôt REST.
A ne pas confondre !
Web Services / SOAP Les web services c’est récupérer des données via HTTP (canal de communication) avec pour
« orthographe » le XML, et pour « grammaire » SOAP.
SOAP indique les règles d’écriture, le comment on écrit pour que ce soit lisible et
compréhensible par quelqu’un qui connait aussi SOAP.
XML c’est l’orthographe de SOAP, je sais écrire un élément, qui contient des attributs etc…
HTTP c’est le canal de communication.
Voilà un exemple de requêtes SOAP :
HTTP/1.1 200 OK
Content-Type: text/xml;
charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-URI">
<Price>34,5</Price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Bref, Les Web Services c’est ça.
Si vous voulez plus d’informations sur SOAP, un bon lien MSDN, en français :
http://msdn.microsoft.com/fr-fr/library/bb469912.aspx
Le gros inconvénient de SOAP c’est que c’est difficilement compréhensible, comme ça en le lisant.
Trop verbeux, trop complexe, bref utilisable par des outils conçus pour (Visual Studio par exemple)
mais pas plus.
REST L’idée de REST (REpresentational State Transfer) c’est d’alléger la communication http entre le client
et le serveur, de la rendre plus simple.
Un peu de lecture sur le sujet :
REST ne définit pas beaucoup de choses si ce n’est :
L’URI comme syntaxe universelle pour adresser des ressources.
Exemple : http://www.foo.com/Clients ou http://www.foo.com/Clients/12
HTTP comme protocole de communicatio,n sans état
Un contenu XML ou JSON en retour
L’avantage de REST, c’est au final d’alléger la communication, de proposer une façon simple de
communiquer et surtout lisible / pratique. Enfin le support de JSON, format « à la mode » pour les
applications web
Le gros problème de REST, c’est que chacun peut définir sa propre convention.
Par exemple, récupérer un client N°12 peut s’écrire comme on veut :
http://foo.com/Clients/12
http://foo.com/Table/Client/Id/12
http://foo.com/Table/Clients?IdClient=12
Et la réponse, XML ou JSON dans la même idée. On pourrait avoir une réponse comme ceci :
<Client> <Id>12</Id> <Nom>Pertus</Nom> <Prenom>Sébastien</Prenom> <DateNaissance>1976-10-23</DateNaissance> <Adresse> <Ville>Toulouse</Ville> <CodePostal>31000</CodePostal> </Adresse> </Client>
Ou comme ceci, pourquoi pas :
<Client Id="12" Nom="Pertus" Prenom="Sébastien" DateNaissance="1976-10-23"> <Adresse Ville="Toulouse" CodePostal="31000" /> </Client>
Ces deux exemples sont parfaitement bien écrits, en XML standard.
Il faut donc que le serveur qui intercepte une requête REST connaisse la « grammaire » utilisée, et
sache aussi comment formater la réponse.
De même le client doit connaitre la structure de la requête REST à envoyer et doit aussi savoir
comment lire la réponse générée par le serveur.
Au final REST ne se compare pas à SOAP, Il n’est pas standardisé, il ne propose pas une structure /
normalisation à respecter.
REST est une architecture de communication (on fait du GET / POST/ PUT … et on récupère du XML /
JSON)
Pour le comparer à SOAP, il faudrait le normaliser un peu, qu’un client puisse interroger un serveur
sans connaitre les données mais en sachant tout de même comment les récupérer / requêter.
Et c’est là qu’intervient …. ODATA
OData OData est une spécification disponible sur http://www.odata.org
OData est là pour cadrer comment on peut faire des requêtes REST, et quel résultat on est censé
récupéré, que ce soit JSON ou XML
Nous en sommes à la version 4 du protocole OData aujourd’hui.
OData au final ce n’est qu’un gros catalogue de règles à respecter pour faire des requêtes REST et
retourner une réponse XML / JSON, correctement formatée et nomenclaturée.
Si vous voulez faire de l’OData, respectez sa convention et vous exposerez de l’OData via REST.
Reprenons l’exemple précédent.
La spécification OData dit que pour appeler l’élément Client dont la clé est 12 et qui fait partie de la
collection Clients, voici le type de requête :
http://localhost:65345/PayNotesService.svc/Clients(12)
Normalisé, documenté, compréhensible par tout le monde
Et la réponse se doit d’être dans ce format-là (j’ai un peu simplifié pour plus de clareté) :
<feed xml:base="…" xmlns=".." xmlns:d="…" xmlns:m="…"> <id>http://localhost:65345/PayNotesService.svc/Clients</id> <title type="text">Clients</title> <updated>2014-04-08T15:36:37Z</updated> <link rel="self" title="Clients" href="Clients" /> <entry> <id>http://localhost:65345/PayNotesService.svc/Clients(10)</id> <category term="PayNotesModel.Client" scheme="…" /> <link rel="edit" title="Client" href="Clients(10)" /> <title /> <updated>2014-04-08T15:36:37Z</updated> <author> <name /> </author> <content type="application/xml"> <m:properties> <d:ClientId m:type="Edm.Int32">10</d:ClientId> <d:Nom>Pertus</d:Nom> <d:Prenom>Sébastien</d:Prenom> <d:DateNaissance m:type="Edm.DateTime">1976-10-23T00:00:00</d:DateNaissance> <d:Ville>Toulouse</d:Ville> <d:CodePostal>31000</d:CodePostal> </m:properties> </content> </entry> </feed>
Et la version JSON :
{ "odata.metadata":"http://localhost:65345/PayNotesService.svc/$metadata#Clients/@Element", "ClientId":10, "Nom":"Pertus", "Prenom":"S\u00e9bastien", "DateNaissance":"1976-10-23T00:00:00", "Ville":"Toulouse", "CodePostal":"31000" }
Maintenant, on part du principe que tout flux implémentant la spec OData, doit être
compréhensible par n’importe quel outil connaissant la spec OData, et le tout en utilisant une
architecture REST.
Voici quelques exemples des requêtes possibles :
Récupérer uniquement certaines colonnes et les 15 premières lignes :
http://localhost:4123/NorthwindServices.svc/Categories?$select=CategoryID,CategoryName
,Description,Products&$top=15
Filtrer les catégories strictement supérieures à 2 :
http://localhost:4123/NorthwindServices.svc/Categories?$filter=CategoryID%20gt%202
Récupérer les produits du 31ème au 50éme :
http://localhost:4123/NorthwindServices.svc/Products?$skip=30&$top=15
Il existe quelques outils pour requêter graphiquement des flux OData. Vous pouvez les retrouvez sur
cette page : http://www.odata.org/ecosystem/#consumers
J’utilise personnellement Sésame, version installée en locale, qui me permet de facilement
interroger des flux locaux (ou distants bien sûr)
Il ne reste plus qu’à comprendre ce qu’est WCF Data Service
WCF Data Service WCF Data Service, c’est le SDK créé par Microsoft pour les technologies de développement basé sur
.NET, qui implémente la spécification OData
Pour faire simple. Supposons que vous vouliez exposer une source de données en OData. Vous
devriez pour se faire connaitre la spécification OData par cœur, générer les documents XML ou JSON
correctement formaté et savoir interprété les requêtes http qui arrivent.
Bref, une montagne de travail pas forcément évident.
C’est là que WCF Data Service intervient. En utilisant le SDK WCF Data Service, vous êtes capable de
créer un serveur web exposant de l’OData, sans vous soucier de connaitre la spécification par cœur !
De même avec WCF Data Service, vous allez être capable d’interroger un serveur OData à l’aide de
requêtes LINQ, qui seront automatiquement transformées en « OData like »
Si vous voulez en savoir plus sur WCF Data Services et l’équipe qui s’en occupe, voici leur blog :
http://blogs.msdn.com/b/odatateam/ et le site MSDN de référence : http://msdn.microsoft.com/en-
us/data/bb931106.aspx
Partie Serveur Nous allons donc créer un projet qui va nous permettre d’exposer nos données sous format OData
grâce à WCF Data Services !
Nous créons une application web vite, qui va se charger d’exposer les données :
Depuis ce site web « vide », nous allons ajouter notre modèle EntityFramework 6.1 qui va nous
permettre de requêter notre serveur de données (je vous renvoie aux précédents modules pour la
marche à suivre) :
A partir de là nous allons ajouter un nouvel élément appelé WCF Data Service 5.6 :
Cet élément est un fichier .svc (qui implémente un ServiceHost, on est bien dans du WCF )
Le fichier *.svc.cs contient une partie code, que nous allons configurer.
Mais avant cela, nous allons devoir mettre à jour WCF Data Services, via nuget :
Activer l’option « Include Prerelease »
Cherchez le mot clé « Microsoft.OData » et installez le package WCF Data Services Entity
Framework Provider :
A partir de là, nous pouvons modifier le fichier .svc, pour qu’il fonctionne correctement :
Voilà le code source par défaut généré :
public class NorthwindServices : DataService< /* TODO: put your data source class name here */ > { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) { // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc. // Examples: // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead); // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; } }
Et voilà le code source modifié :
public class NorthwindServices : EntityFrameworkDataService< NorthwindEntities > { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; } }
Ce qui est très important à noter :
Nous avons remplacé DataService<T> par EntityFrameworkDataService<T> : une obligation depuis
la version 6 d’Entity Framework.
Nous avons spécifié « * » dans les règles d’accès, autorisant toutes les opérations CRUD sur notre
base.
A partir de là, nous pouvons lancer notre projet web (en ayant bien spécifié la page de démarrage
sur le fichier .svc)
Evidemment toutes les opérations classiques sont autorisées :
http://localhost:4123/NorthwindServices.svc/Categories
http://localhost:4123/NorthwindServices.svc/Categories(1)
…
Partie Client Nous allons ajouter à notre projet, un nouveau projet de type console qui référencera le SDK WCF
Data Service et qui nous permettra d’interroger notre serveur OData local
Sans le SDK WCF Data Service Client Avant de montrer le côté pratique du SDK WCF Data Service coté client, voici la méthode de
récupération d’un flux OData, sans aide si ce n’est une connexion http.
Dans l’ordre il faut :
1. Générer la requête http correcte (Bien connaitre la syntaxe OData du coup)
2. Avoir préalablement créé les classes représentant les entités (voir $metadata)
3. Récupérer le flux dans une chaine de caractère
4. Parser ce flux et remplir la collection (heureusement JSON.Net va nous aider)
Bon sans être si complexe, le principal problème c’est de connaitre la structure, et les requêtes
OData à spécifier.
HttpClient httpClient = new HttpClient(); //url de base Uri baseUrl = new Uri("http://localhost:4123/NorthwindServices.svc/"); // url d'un filtre sur la collection Customers Uri categoriesUrl = new Uri(baseUrl, "Customers/?$filter=startswith(CustomerID, 'A')"); // JSON httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // récupération réponse var response = await httpClient.GetAsync(categoriesUrl); response.EnsureSuccessStatusCode(); // Récupération chaine de caractère string responseBodyAsText = await response.Content.ReadAsStringAsync(); // utilisation d'un dynamic pour récupérer la value dynamic json = JsonConvert.DeserializeObject(responseBodyAsText); // Cast var lstCustomers = json.value.ToObject<List<Customer>>();
Là où ça se complique c’est lors de l’ajout ou la modification d’une entité …
Avec le SDK WCF Data Service Client Le projet créé, nous référençons directement (via le menu Add Service Reference) le lien vers le flux
OData :
Automatiquement, l’ensemble des assemblies nécessaires sont installée via nuget :
Comme on l’a vu dans les divers modules précédents, l’ajout de la référence a généré le code
complet permettant d’utiliser en local les classes de bases de la base Northwind.