Traduction

Cet article est la traduction la plus fidèle possible de l'article original de Carlos Figueira, Creating ASP.NET Web APIs on Azure Web Sites.

Création d'API Web ASP.NET sur Azure Web Sites

Le mois dernier (en juin 2012) les nouvelles fonctionnalités de Windows Azure ont été publiées, et l'une d'entre elles que j'avais trouvée plutôt intéressante était les « Sites Web ». Actuellement j'ai un compte chez GoDaddy.com où j'héberge mes « projets fétiches », et maintenant que Windows Azure possède une fonctionnalité semblable pour un plan de tarification analogue (pour la préversion nous pouvons avoir jusqu'à dix sites sans frais, avec une utilisation des ressources limitée), je me suis senti obligé « d'utiliser mon propre produit » et de l'essayer. Et je l'ai vraiment aimé - notamment l'intégration avec le contrôle de code source de Git, qui fait que télécharger de nouveaux éléments vers le site semble un jeu d'enfant. Avant de passer pour un chauvin, je m'explique : j'ai préféré l'intégration Git à l'interface GoDaddy car je préfère travailler avec les interfaces en ligne de commande. Si vous aimez les interfaces graphiques, vous pouvez utiliser quelque chose comme un client FTP pour communiquer avec GoDaddy ou l'un des nombreux shells Git (que je n'ai pas essayés), donc lequel serait le meilleur dépendra de votre avis sur les outils.

J'ai ainsi décidé de convertir un de mes vieux projets que j'ai hébergés sur le compte GoDaddy afin de fonctionner dans un site Web Azure. Le projet, un outil qui convertit un document JSON en une classe (ou une série de classes) et un contrat d'exploitation pouvant être utilisés dans WCF, a été écrit en utilisant quelques classes d'un projet Codeplex qui n'est plus supporté (les API Web WCF). Donc, en migrant vers Azure, j'ai décidé également d'essayer l'intégration entre cela et le remplacement à ce projet, les API Web ASP.NET. Voici un compte-rendu étape par étape de ce que j'ai fait, en espérant que vous le trouverez utile lorsque vous essaierez de faire quelque chose de similaire.

Donc, voici un procédé bien détaillé étape par étape de ce que j'ai fait - et dans le même sens que ce que vous feriez - afin de créer mon API et de l'héberger dans Azure. J'espère que vous aimez les longs articles…

Si vous êtes uniquement intéressé par l'outil pour convertir JSON en contrats de données : retrouvez-le sur http://jsontodatacontract.azurewebsites.net, ou vous pouvez obtenir les sources sur MSDN Code Gallery.

Créer le site

La première chose à faire c'est de créer le nouveau site Web qui hébergera l'API. J'ai essayé avec le nom « jsontodatacontract » et il était disponible :

Image non disponible

Après avoir créé le site Web, il existe plusieurs options pour le déployer. Nous pourrions utiliser l'option « Publier » de n'importe quel projet Web (ou site Web) dans Visual Studio, ou nous pouvons aussi utiliser le système de contrôle de code source intégré dans les sites Web. Puisque je souhaite avoir le contrôle du code source et que j'aime la simplicité de Git, je vais choisir cette option.

Image non disponible

Maintenant le dépôt est créé (en un clic !), et est prêt à l'emploi. La page suivante montre les prochaines étapes à suivre afin de télécharger des données vers le site.

Image non disponible

Créer le projet

Jusqu'à présent nous n'avons pas de données à pousser vers le site Web, prenons donc un peu de recul du portail Azure pour un moment, et créons un nouveau projet que nous allons utiliser. Puisque tout ce que je veux (pour l'instant) c'est construire un service, je vais créer un projet vide, et donc je vais utiliser une application Web ASP.NET vide plutôt que l'application MVC4 complète. Cela rendra notre code aussi minimal que possible, mais nous allons nous-même devoir gérer des choses - qui ne sont pas très dures comme nous le verrons sous peu - telles que le routage. Un autre avantage de cette méthode (le projet vide) est que nous n'avons pas besoin d'installer quoi que ce soit, et pour obtenir les modèles ASP.NET MVC 4, eh bien vous devez installer les modèles ASP.NET MVC 4.

Au moment de rédiger cet article, les modèles ASP.NET MVC 4 sont disponibles en version RC, et beaucoup de gens - moi compris - n'aiment pas installer des logiciels en préversion sur leurs postes. La version RC est déjà d'une bonne qualité, mais puisque dans ce cas je n'en ai pas besoin, j'aimerai garder les choses simples dans la mesure du possible.

Donc, ouvrons la boîte de dialogue « Nouveau projet » et créons une « Application Web ASP.NET vide ». Je vais l'enregistrer dans le répertoire c:\git, mais ce n'est qu'une préférence personnelle (la racine de mes dépôts Git), elle peut être créée dans n'importe quel dossier sur votre poste. Un des paramètres que nous devrions utiliser est la case à cocher « Créer le répertoire pour la solution », car cela nous permettra d'utiliser la fonctionnalité « NuGet Package Restore » que j'aborderai par la suite.

Image non disponible

Une fois le projet créé, ajoutons une référence aux binaires pour l'API Web. Faites un clic droit sur le projet, sélectionnez « Manage NuGet Packages… », et cela fera apparaître la boite de dialogue de NuGet où nous pouvons rechercher « webapi » et sélectionner le paquet « Microsoft ASP.NET Web API (RC) » (tant que la version finale n'est pas disponible). Cliquer sur « Install » va télécharger ce paquet (et toutes ses dépendances). Cela les ajoutera également en tant que références au projet, afin qu'elles puissent être utilisées immédiatement.

Image non disponible

Une parenthèse ici - j'ai commencé à utiliser NuGethttp://www.nuget.org/ il y a à peu près un an, et je l'aime vraiment. C'est une fonctionnalité qui est installée par défaut sur Visual Studio 2012. Pour Visual Studio 2010, vous pouvez l'installer à partir d'un lien sur la page principale de NuGet : .

Mon seul grief est que cela ne fonctionne pas sur les éditions Express de Visual Studio 2010 (C# ou VB) - mais cela fonctionne sur Visual Web Developer. Par contre, je pense que cela fonctionnera sur les éditions Express de Visual Studio 2012.

Bon, revenons au projet. Nous devons créer une classe contrôleur qui implémente notre service. Dans les API Web, les classes contrôleur peuvent être définies n'importe où dans le projet, mais pour rester conforme à la convention, je vais l'ajouter dans un dossier nommé « Controllers » que j'ajouterai au projet.

Image non disponible

Et nous pouvons maintenant ajouter notre classe contrôleur dans ce dossier en faisant un clic droit sur le dossier et en sélectionnant « Ajouter » puis « Nouvel élément », ensuite en sélectionnant une nouvelle « Classe contrôleur d'API Web »

Image non disponible

Pour l'instant, enlevons l'implémentation de cette classe et ajoutons une paire de méthodes Post/Get pour voir si le déploiement vers Azure fonctionnera.

 
Sélectionnez
  1.     public class JsonToDataContractController : ApiController 
  2.     { 
  3.         // POST api/<controller> 
  4.         public HttpResponseMessage Post(HttpRequestMessage value) 
  5.         { 
  6.             var response = Request.CreateResponse(HttpStatusCode.OK); 
  7.             response.Content = new StringContent("I'll be running on an Azure Web Site!"); 
  8.             return response; 
  9.         } 
  10.       
  11.         public HttpResponseMessage Get() 
  12.         { 
  13.             var response = this.Request.CreateResponse(HttpStatusCode.OK); 
  14.             response.Content = new StringContent("I'll be running on an Azure Web Site!"); 
  15.             return response; 
  16.         } 
  17.     } 

Autre chose concernant le projet : puisque nous avons utilisé un modèle vide, nous devons nous-même ajouter le code de routage. Ajoutons, donc, une nouvelle « Classe d'application globale »

Image non disponible

Et ajoutez le routage au code :

 
Sélectionnez
  1.     using System; 
  2.     using System.Web.Http; 
  3.       
  4.     namespace JsonToDataContract 
  5.     { 
  6.         public class Global : System.Web.HttpApplication 
  7.         { 
  8.             protected void Application_Start(object sender, EventArgs e) 
  9.             { 
  10.                 GlobalConfiguration.Configuration.Routes.MapHttpRoute( 
  11.                     name: "api", 
  12.                     routeTemplate: "api/{controller}", 
  13.                     defaults: new { controller = "JsonToDataContract" }); 
  14.             } 
  15.         } 
  16.     } 

À ce moment, nous pouvons effectuer un « F5 » sur notre application pour voir si elle fonctionne. Par défaut le projet naviguera vers la racine « / », mais notre contrôleur se trouve à l'URL « api/ » (basée sur le modèle de route), nous devons donc naviguer vers cet emplacement.

Image non disponible

Et comme nous avons aussi ajouté une opération Post, nous devrions être capable de l'appeler également, chose que je peux faire avec Fiddler :

Image non disponible

Ajouter le contrôle de code source en utilisant Git

Bon, nous disposons à présent d'une API Web fonctionnelle, nous pouvons donc démarrer le processus de déploiement. La dernière page du portail indiquait ce qu'il faut faire, allons donc à la racine de notre application (c:\git\JsonToDataContract) et initialisons notre dépôt Git.

Image non disponible

Nous pouvons maintenant voir quels sont les fichiers que Git souhaitent suivre en utilisant la commande git status

Image non disponible

Il y a deux choses que Git souhaite suivre mais que nous n'avons pas vraiment besoin de déployer. La première est le fichier .suo (« Solution User Options ») de la solution, qui n'a pas besoin d'être partagé. L'autre ce sont les paquets NuGet qui sont stockés dans le répertoire « packages/ ». Git, comme d'autres systèmes de gestion de versions décentralisés, ne fonctionne pas très bien avec les fichiers binaires, car leur mise à jour peut entraîner le dépôt Git à croître énormément au fil du temps. Heureusement, NuGet possède une fonctionnalité appelée NuGet Package Restore, qui nous permet de contourner la vérification des paquets, et pendant la compilation elle va télécharger en local tous les paquets manquants.

Pour réaliser cela, faites un clic droit sur la solution dans l'Explorateur de solutions de VS, et choisissez l'option « Activer la restauration du package NuGet ».

Image non disponible

Ce qu'a fait la fonctionnalité est d'ajouter un nouveau dossier de solution (.nuget), et dedans d'ajouter un nouveau fichier .targets, et un exécutable NuGet qui peut être utilisé pendant la compilation pour télécharger les paquets manquants.

Image non disponible

Nous pouvons maintenant omettre le répertoire des paquets (tout comme le fichier .suo) de Git, et pour réaliser cela nous aurons besoin d'un fichier .gitignore à la racine Git (dans mon cas, c:\git\JsonToDataContract\.gitignore).

Image non disponible

Nous pouvons maintenant ajouter le projet et voir tout ce qui fera l'objet d'un commit.

Image non disponible

Et finalement, faisons un commit de nos modifications :

Image non disponible

Déployer vers Azure

Donc, nous avons effectué un commit de nos modifications vers le dépôt local, mais jusqu'à présent rien n'a été poussé vers Azure. Faisons cela en suivant, une fois de plus, les instructions sur la page Azure Web Sites :

Image non disponible

Plein de choses se sont produites lorsque nous avons poussé vers le site Web. D'abord, nous avons poussé notre dépôt vers le serveur. Là-bas, une fois le transfert effectué, le site a démarré le déploiement automatique en compilant le projet. Remarquez qu'étant donné nous avions omis les paquets NuGet (mais activé la restauration des paquets), les paquets aussi ont été téléchargés pendant la compilation. Et quand la compilation a été effectuée, le site a été déployé. Nous pouvons donc aller sur http://jsontodatacontract.azurewebsites.net/api et voir la même page que nous avions vue en local :

Image non disponible

Et notre API Web tourne sur Azure !

Point de contrôle

Bon, qu'avons-nous jusqu'ici ? Nous avons créé un site Web sur Azure, mis en place la publication Git, créé un projet utilisant Web API via NuGet, et déployé ce projet sur Azure. En ce qui concerne la question de « comment créer et déployer une API Web sur Azure » c'est fait. Je vais, cependant, continuer afin de terminer le projet que je m'étais fixé.

Mettre à jour le contrôleur - convertir JSON en classes

Bon, faisons le contrôleur accomplir ce qu'il est censé faire. Comme j'avais déjà un projet qui faisait quelque chose de similaire, je vais réutiliser une partie du code de ce projet-là dans celui-ci, et laissez-moi commencer par vous dire que ce ne sera sûrement pas le plus beau code que vous allez voir, mais comme il fonctionne j'ai décidé de ne pas trop le tripatouiller.

La tâche de convertir du JSON arbitraire en classes qui le représente peut être décomposée en deux étapes. D'abord, nous devons examiner le JSON et voir s'il possède une structure qui peut effectivement être représentée dans des classes - il existe certains qui ne l'ont pas, tels que les tableaux contenant des objets et des primitifs. En faisant cela, nous pouvons charger le JSON dans une structure de mémoire, similaire à un DOM, avec des informations sur les types. Ensuite, nous devons traverser ce DOM et le convertir en classes que nous allons utiliser pour consommer et produire ce JSON.

Pour la première partie, je vais définir une classe appelée JsonRoot, pouvant représenter soit un type primitif (chaîne, booléen, nombre), soit un type complexe qui contient des membres. Les membres (ou la racine elle-même) peuvent faire partie d'un tableau, donc nous stockons également le rang (ou nombre de dimensions) du tableau dans le type JsonRoot (« rang » est un terme qui présente plusieurs sens couramment utilisés avec un tableau rectangulaire, mais dans ce scénario cela veut effectivement dire des tableaux en escalier pris en charge par les sérialiseurs). Remarquez que cette classe pourrait (ou peut-être, devrait ?) être mieux conçue, divisée en deux de manière à ce que chaque type ait son comportement, mais je ne vais pas m'aventurer de ce côté-là, du moins pas dans cette version.

 
Sélectionnez
  1.     public class JsonRoot 
  2.     { 
  3.         public bool IsUserDefinedType { get; private set; } 
  4.         public Type ElementType { get; private set; } 
  5.         public string UserDefinedTypeName { get; private set; } 
  6.         public int ArrayRank { get; private set; } 
  7.         public IDictionary<string, JsonRoot> Members { get; private set; } 
  8.       
  9.         private JsonRoot Parent { get; set; } 
  10.       
  11.         private JsonRoot(Type elementType, int arrayRank) 
  12.         { 
  13.             this.Members = new Dictionary<string, JsonRoot>(); 
  14.             this.IsUserDefinedType = false; 
  15.             this.ElementType = elementType; 
  16.             this.ArrayRank = arrayRank; 
  17.         } 
  18.       
  19.         private JsonRoot(string userDefinedTypeName, int arrayRank, IDictionary<string, JsonRoot> members) 
  20.         { 
  21.             this.IsUserDefinedType = true; 
  22.             this.UserDefinedTypeName = userDefinedTypeName; 
  23.             this.ArrayRank = arrayRank; 
  24.             this.Members = members; 
  25.         } 
  26.       
  27.         public static JsonRoot ParseJsonIntoDataContract(JToken root, string rootTypeName) 
  28.         { 
  29.             if (root == null || root.Type == JTokenType.Null) 
  30.             { 
  31.                 return new JsonRoot(null, 0); 
  32.             } 
  33.             else 
  34.             { 
  35.                 switch (root.Type) 
  36.                 { 
  37.                     case JTokenType.Boolean: 
  38.                         return new JsonRoot(typeof(bool), 0); 
  39.                     case JTokenType.String: 
  40.                         return new JsonRoot(typeof(string), 0); 
  41.                     case JTokenType.Float: 
  42.                         return new JsonRoot(typeof(double), 0); 
  43.                     case JTokenType.Integer: 
  44.                         return new JsonRoot(GetClrIntegerType(root.ToString()), 0); 
  45.                     case JTokenType.Object: 
  46.                         return ParseJObjectIntoDataContract((JObject)root, rootTypeName); 
  47.                     case JTokenType.Array: 
  48.                         return ParseJArrayIntoDataContract((JArray)root, rootTypeName); 
  49.                     default: 
  50.                         throw new ArgumentException("Cannot work with JSON token of type " + root.Type); 
  51.                 } 
  52.             } 
  53.         } 
  54.     } 

Parser des types primitifs est une chose triviale, comme démontré ci-dessus. Parser des objets n'est pas difficile non plus - parser les membres de manière récursive et créer un type défini par l'utilisateur avec ces membres. Quand nous arrivons aux tableaux, c'est là que commence le problème. Les tableaux JSON peuvent contenir des objets arbitraires, donc nous avons besoin d'une logique de fusion de manière à ce que deux éléments similaires puissent être représentés par le même type de données.

Voici quelques exemples pour illustrer ce point :

  • le tableau [1, 1234, 1234567, 12345678901] peut dans un premier temps être représenté comme un tableau de valeurs Int32, mais la dernière valeur est au-delà de la portée de ce type, donc nous devons utiliser un tableau de Int64 à la place ;
  • presque tous les éléments dans le tableau [true, false, false, null, true] peuvent être représentés par Boolean, sauf pour le quatrième. Dans ce cas, nous pouvons utiliser Nullable<Boolean> à la place ;
  • ce tableau [1, 2, “hello”, false] pourrait potentiellement être représenté en tant qu'un tableau d'objets, mais cela nous fait perdre trop d'informations, j'ai donc décidé qu'il ne serait pas implémenté dans cette version ;
  • les tableaux d'objets sont plus complexes. Afin de fusionner deux éléments d'un tableau, nous devons fusionner les types de tous les membres des objets, y compris les membres supplémentaires et ceux manquants. Ce tableau - [{“nom”:”Scooby Doo”, “race”:”great dane”}, {“nom”:”Shaggy”,”age”:"19}] - nécessiterait un type avec trois membres (nom, race, age). Et ainsi de suite.

Donc, voici comment nous pouvons parser un tableau en tant que JsonRoot. Après avoir essayé de fusionner tous les éléments de ce tableau dans un type JsonRoot, nous allons créer un nouvel objet JsonRoot d'incrémentation de la propriété ArrayRank.

 
Sélectionnez
  1.     private static JsonRoot ParseJArrayIntoDataContract(JArray root, string rootTypeName) 
  2.     { 
  3.         if (root.Count == 0) 
  4.         { 
  5.             return new JsonRoot(null, 1); 
  6.         } 
  7.       
  8.         JsonRoot first = ParseJsonIntoDataContract(root[0], rootTypeName); 
  9.         for (int i = 1; i < root.Count; i++) 
  10.         { 
  11.             JsonRoot next = ParseJsonIntoDataContract(root[i], rootTypeName); 
  12.             JsonRoot mergedType; 
  13.             if (first.CanMerge(next, out mergedType)) 
  14.             { 
  15.                 first = mergedType; 
  16.             } 
  17.             else 
  18.             { 
  19.                 throw new ArgumentException(string.Format("Cannot merge array elements {0} ({1}) and {2} ({3})", 
  20.                     0, root[0], i, root[i])); 
  21.             } 
  22.         } 
  23.       
  24.         if (first.IsUserDefinedType) 
  25.         { 
  26.             return new JsonRoot(first.UserDefinedTypeName, first.ArrayRank + 1, first.Members); 
  27.         } 
  28.         else 
  29.         { 
  30.             return new JsonRoot(first.ElementType, first.ArrayRank + 1); 
  31.         } 
  32.     } 

Le code pour fusionner les deux types est disponible dans l'échantillon sur MSDN Code Gallery (le lien à la fin de cet article).

Maintenant, nous avons une structure de données qui nous dit quels types nous devons générer. Passons à la partie génération de code. Dans cet exemple, j'utilise les types dans l'espace de noms System.CodeDom car il m'offre sans frais la génération dans plusieurs langages. Je vais ajouter une nouvelle classe, JsonRootCompiler, qui possède une méthode qui va écrire tous les types correspondant à l'objet JsonRoot donné (et ainsi que la racine de tous les membres de cet objet) dans un text writer.

 
Sélectionnez
  1.     public class JsonRootCompiler 
  2.     { 
  3.         private SerializationModel serializationModel; 
  4.         private string language; 
  5.       
  6.         /// <summary> 
  7.         /// Creates a new instance of the JsonRootCompiler class. 
  8.         /// </summary> 
  9.         /// <param name="language">The programming language in which the code will be generated.</param> 
  10.         /// <param name="serializationModel">The serialization model used in the classes.</param> 
  11.         public JsonRootCompiler(string language, SerializationModel serializationModel) 
  12.         { 
  13.             this.language = language; 
  14.             this.serializationModel = serializationModel; 
  15.         } 
  16.       
  17.         public void GenerateCode(JsonRoot root, TextWriter writer) 
  18.         { 
  19.             CodeCompileUnit result = new CodeCompileUnit(); 
  20.             result.Namespaces.Add(new CodeNamespace()); 
  21.             GenerateType(result.Namespaces[0], root, new List<string>()); 
  22.             CodeDomProvider provider = CodeDomProvider.CreateProvider(this.language); 
  23.             CodeGeneratorOptions options = new CodeGeneratorOptions(); 
  24.             options.BracingStyle = "C"; 
  25.             provider.GenerateCodeFromCompileUnit(result, writer, options); 
  26.         } 
  27.       
  28.         private string GenerateType(CodeNamespace ns, JsonRoot root, List<string> existingTypes) 
  29.         { 
  30.             if (!root.IsUserDefinedType) return null; 
  31.       
  32.             CodeTypeDeclaration rootType = new CodeTypeDeclaration(GetUniqueDataContractName(root.UserDefinedTypeName, existingTypes)); 
  33.             existingTypes.Add(rootType.Name); 
  34.             rootType.Attributes = MemberAttributes.Public; 
  35.             rootType.IsPartial = true; 
  36.             rootType.IsClass = true; 
  37.             ns.Types.Add(rootType); 
  38.             rootType.Comments.Add( 
  39.                 new CodeCommentStatement( 
  40.                     string.Format( 
  41.                         "Type created for JSON at {0}", 
  42.                         string.Join(" --> ", root.GetAncestors())))); 
  43.       
  44.             AddAttributeDeclaration(rootType, rootType.Name, root.UserDefinedTypeName); 
  45.             AddMembers(ns, rootType, root, existingTypes); 
  46.             return rootType.Name; 
  47.         } 
  48.     } 

Une fois de plus, le gros de l'implémentation peut être retrouvé dans l'échantillon sur MSDN Code Gallery.

Et maintenant que nous avons les deux morceaux dont nous avons besoin, nous pouvons mettre à jour le code pour que le contrôleur les utilise. La méthode Post possède quatre paramètres, trois de type string (qui, par défaut, devraient arriver par le biais de l'URI de la requête, en tant que paramètres de chaînes de requête), et un de type JToken qui peut être lu par le formateur JSON dans le framework Web API (il sera lu à partir du corps de la requête).

 
Sélectionnez
  1.     public HttpResponseMessage Post(JToken value, string rootTypeName, string language, string serializationModel) 
  2.     { 
  3.         JsonRoot root = JsonRoot.ParseJsonIntoDataContract(value, rootTypeName); 
  4.         StringBuilder sb = new StringBuilder(); 
  5.         using (StringWriter sw = new StringWriter(sb)) 
  6.         { 
  7.             JsonRootCompiler compiler = new JsonRootCompiler( 
  8.                 language, 
  9.                 (SerializationModel)Enum.Parse(typeof(SerializationModel), serializationModel, true)); 
  10.             compiler.GenerateCode(root, sw); 
  11.             var response = Request.CreateResponse(HttpStatusCode.OK); 
  12.             response.Content = new StringContent(sb.ToString()); 
  13.             return response; 
  14.         } 
  15.     } 

Testons-la maintenant. Étant donné que nous n'avons qu'une méthode Post, nous allons devoir soit créer un client personnalisé, soit utiliser quelque chose comme Fiddler pour le faire.

Image non disponible

Création d'un « front-end » simple

À présent notre API est réalisée et peut être déployée sur Azure via Git. Mais, afin de rendre le site Web plus utilisable, créons un « front-end » simple où les utilisateurs n'auront pas besoin de faire appel à des outils tels que Fiddler pour générer du JSON. Mes compétences en conception sont, au mieux, assez rudimentaires, donc je n'essaierai même pas de faire des trucs particuliers, et me contenterai plutôt d'utiliser quelques contrôles HTML. Ajoutons d'abord une nouvelle page HTML. Basée sur la configuration de mon site Web Azure, le premier fichier qu'il va rechercher lorsqu'on y naviguera se nomme Default.htm (vous pouvez voir cela au bas de la page « Configurer » dans le portail), donc créons-en un dans notre projet.

Image non disponible

Et ajoutons-y un peu de code :

 
Sélectionnez
  1.     <body> 
  2.         <h1>JSON to Data Contract (or JSON.NET) types</h1> 
  3.         <p>Root class name: <input type="text" id="rootClassName" value="RootClass" size="50" /></p> 
  4.         <p>Output programming language: 
  5.             <select id="progLanguage"> 
  6.                 <option value="CS" selected="selected">C#</option> 
  7.                 <option value="VB">VB.NET</option> 
  8.             </select> 
  9.         </p> 
  10.         <p>Serialization Model: 
  11.             <select id="serializationModel"> 
  12.                 <option value="DataContractJsonSerializer" selected="selected">DataContract</option> 
  13.                 <option value="JsonNet">JSON.NET</option> 
  14.             </select> 
  15.         </p> 
  16.         <p><b>JSON document:</b><br /> 
  17.          <textarea id="jsonDoc" rows="10" cols="60"></textarea></p> 
  18.         <p><input type="button" id="btnGenerate" value="Generate code!" /></p> 
  19.         <p><b>Classes:</b><br /> 
  20.          <textarea id="result" rows="10" cols="60"></textarea></p> 
  21.     </body> 

Il nous faut, maintenant, brancher le bouton afin d'appeler notre API. Nous pourrions le faire en utilisant l'objet XmlHttpRequest natif, mais j'ai constaté qu'utiliser jQuery est beaucoup plus simple, et nous pouvons utiliser NuGet pour ajouter une référence à jQuery à notre projet, alors pourquoi pas ?

Image non disponible

Nous devons ajouter une référence à jQuery.js sur le fichier Default.htm, la méthode la plus facile est de simplement glisser le fichier jQuery.1.7.2.js du dossier de scripts (là où le paquet NuGet l'a créé) et de le déposer au sein de la section <head> dans le fichier HTML.

 
Sélectionnez
  1.     <script type="text/javascript"> 
  2.         $("#btnGenerate").click(function () { 
  3.             var url = "./api/JsonToDataContract?language=" + $("#progLanguage").val() + 
  4.                 "&rootTypeName=" + $("#rootClassName").val() + 
  5.                 "&serializationModel=" + $("#serializationModel").val(); 
  6.             var body = $("#jsonDoc").val(); 
  7.             $.ajax({ 
  8.                 url: url, 
  9.                 type: "POST", 
  10.                 contentType: "application/json", 
  11.                 data: body, 
  12.                 dataType: "text", 
  13.                 success: function (result) { 
  14.                     $("#result").val(result); 
  15.                 }, 
  16.                 error: function (jqXHR) { 
  17.                     $("#result").val("Error: " + jqXHR.responseText); 
  18.                 } 
  19.             }); 
  20.         }); 
  21.     </script> 

Lorsque nous cliquons sur le bouton, il va ensuite envoyer une requête à l'API Web, et nous pouvons le tester.

Image non disponible

Redéploiement vers Azure

Bon, nous approchons du but, je vous le promets. Revenons-en à notre invite de commande et voyons ce qu'est en train de suivre Git maintenant, en utilisant git status :

Image non disponible

Nous avons plusieurs éléments qu'il nous faut ajouter à la zone de transit, faisons donc cela. Dépendant de la configuration de votre client Git, vous pourriez voir apparaître des avertissements au sujet des disparités CR/LF dans les fichiers jQuery, qui peuvent toutefois être ignorés sans risque.

Image non disponible

Faisons, maintenant, un commit des modifications en local :

Image non disponible

Et nous sommes enfin prêts à pousser vers Azure :

Image non disponible

Le déploiement a de nouveau réussi ! Ce qui veut dire que le tour devrait être joué. Essayons de naviguer vers http://jsontodatacontract.azurewebsites.net/, et essayons le service...

Image non disponible

Et ça fonctionne ! Sur le nuage !

Conclusion

Ce doit probablement être le plus long article que j'ai rédigé, mais je ne pense pas que ce scénario soit complexe. J'ai voulu donner une description complète, étape par étape, sur comment développer des API Web ASP.NET et les déployer sur Azure Web Sites.

Liens

Remerciements

Je tiens ici à remercier Carlos Figueira de m'avoir autorisé à traduire son article.
Je remercie tomlev pour sa relecture technique et ses propositions.
Je remercie également ClaudeLELOUP pour sa relecture orthographique et ses propositions.