Tutoriel : créer et déployer une application avec un service frontal API Web ASP.NET Core et un service principal avec étatTutorial: Create and deploy an application with an ASP.NET Core Web API front-end service and a stateful back-end service

Ce tutoriel est la première partie d’une série d’étapes.This tutorial is part one of a series. Vous allez découvrir comment créer une application Azure Service Fabric avec un service frontal API Web ASP.NET Core et un service principal avec état pour stocker vos données.You will learn how to create an Azure Service Fabric application with an ASP.NET Core Web API front end and a stateful back-end service to store your data. Lorsque vous avez terminé, vous disposez d’une application de vote avec un composant web frontal ASP.NET Core qui enregistre les résultats de vote dans un service principal avec état dans le cluster.When you're finished, you have a voting application with an ASP.NET Core web front-end that saves voting results in a stateful back-end service in the cluster. Si vous ne souhaitez pas créer l’application de vote manuellement, vous pouvez télécharger le code source pour obtenir l’application terminée et passer directement au Guide de l’exemple d’application de vote.If you don't want to manually create the voting application, you can download the source code for the completed application and skip ahead to Walk through the voting sample application. Si vous préférez, vous pouvez également regarder une vidéo de procédure pas-à-pas de ce tutoriel.If you prefer, you can also watch a video walk-through of this tutorial.

API front-end AngularJS+ASP.NET - Connexion à un service back-end avec état dans Service Fabric

Dans ce premier volet, vous apprenez à :In part one of the series, you learn how to:

  • Créer un service API Web ASP.NET Core en tant que service fiable avec étatCreate an ASP.NET Core Web API service as a stateful reliable service
  • Créer un service d’application Web ASP.NET Core en tant que service web sans étatCreate an ASP.NET Core Web Application service as a stateless web service
  • Utiliser le proxy inverse pour communiquer avec le service avec étatUse the reverse proxy to communicate with the stateful service

Cette série de tutoriels vous montre comment effectuer les opérations suivantes :In this tutorial series you learn how to:

Conditions préalables requisesPrerequisites

Avant de commencer ce tutoriel :Before you begin this tutorial:

Créer un service API Web ASP.NET en tant que service fiableCreate an ASP.NET Web API service as a reliable service

Commencez par créer le web frontal de l’application de vote à l’aide d’ASP.NET Core.First, create the web front-end of the voting application using ASP.NET Core. ASP.NET Core est une infrastructure légère de développement web inter-plateformes, que vous pouvez utiliser pour créer des API web et d’interfaces utilisateur web modernes.ASP.NET Core is a lightweight, cross-platform web development framework that you can use to create modern web UI and web APIs. Pour bien comprendre comment ASP.NET Core s’intègre avec Service Fabric, il est vivement recommandé de lire l’article ASP.NET Core dans le modèle Reliable Services de Service Fabric.To get a complete understanding of how ASP.NET Core integrates with Service Fabric, we strongly recommend reading through the ASP.NET Core in Service Fabric Reliable Services article. Pour l’instant, vous pouvez suivre ce tutoriel pour démarrer rapidement.For now, you can follow this tutorial to get started quickly. Pour en savoir plus sur ASP.NET Core, consultez la Documentation d’ASP.NET Core.To learn more about ASP.NET Core, see the ASP.NET Core Documentation.

  1. Lancez Visual Studio en tant qu’administrateur.Launch Visual Studio as an administrator.

  2. Créez un projet en sélectionnant Fichier->Nouveau->Projet.Create a project with File->New->Project.

  3. Dans la boîte de dialogue Nouveau projet, sélectionnez Cloud > Application Service Fabric.In the New Project dialog, choose Cloud > Service Fabric Application.

  4. Nommez l’application Voting, puis cliquez sur OK.Name the application Voting and click OK.

    Boîte de dialogue Nouveau projet dans Visual Studio

  5. Dans la page Nouveau service Service Fabric, choisissez ASP.NET Core sans état et nommez votre service VotingWeb, puis cliquez sur OK.On the New Service Fabric Service page, choose Stateless ASP.NET Core, name your service VotingWeb, then click OK.

    Choix du service web ASP.NET dans la boîte de dialogue Nouveau service

  6. La page suivante fournit un ensemble de modèles de projets ASP.NET Core.The next page provides a set of ASP.NET Core project templates. Pour ce tutoriel, sélectionnez Application web (Model-View-Controller) , puis cliquez sur OK.For this tutorial, choose Web Application (Model-View-Controller), then click OK.

    Choisir le type de projet ASP.NET

    Visual Studio crée une application et un projet de service, et les affiche dans l’Explorateur de solutions.Visual Studio creates an application and a service project and displays them in Solution Explorer.

    Explorateur de solutions après la création de l’application avec un service API Web ASP.NET Core

Mettre à jour le fichier site.jsUpdate the site.js file

Ouvrez wwwroot/js/site.js.Open wwwroot/js/site.js. Remplacez son contenu par le code JavaScript suivant utilisé par les vues d’accueil, puis enregistrez vos modifications.Replace its contents with the following JavaScript used by the Home views, then save your changes.

var app = angular.module('VotingApp', ['ui.bootstrap']);
app.run(function () { });

app.controller('VotingAppController', ['$rootScope', '$scope', '$http', '$timeout', function ($rootScope, $scope, $http, $timeout) {

    $scope.refresh = function () {
        $http.get('api/Votes?c=' + new Date().getTime())
            .then(function (data, status) {
                $scope.votes = data;
            }, function (data, status) {
                $scope.votes = undefined;
            });
    };

    $scope.remove = function (item) {
        $http.delete('api/Votes/' + item)
            .then(function (data, status) {
                $scope.refresh();
            })
    };

    $scope.add = function (item) {
        var fd = new FormData();
        fd.append('item', item);
        $http.put('api/Votes/' + item, fd, {
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }
        })
            .then(function (data, status) {
                $scope.refresh();
                $scope.item = undefined;
            })
    };
}]);

Mettre à jour le fichier Index.cshtmlUpdate the Index.cshtml file

Ouvrez le fichier Views/Home/Index.cshtml. Il s’agit de la vue spécifique au contrôleur Home.Open Views/Home/Index.cshtml, the view specific to the Home controller. Remplacez son contenu par la commande suivante, puis enregistrez vos modifications.Replace its contents with the following, then save your changes.

@{
    ViewData["Title"] = "Service Fabric Voting Sample";
}

<div ng-controller="VotingAppController" ng-init="refresh()">
    <div class="container-fluid">
        <div class="row">
            <div class="col-xs-8 col-xs-offset-2 text-center">
                <h2>Service Fabric Voting Sample</h2>
            </div>
        </div>

        <div class="row">
            <div class="col-xs-8 col-xs-offset-2">
                <form class="col-xs-12 center-block">
                    <div class="col-xs-6 form-group">
                        <input id="txtAdd" type="text" class="form-control" placeholder="Add voting option" ng-model="item"/>
                    </div>
                    <button id="btnAdd" class="btn btn-default" ng-click="add(item)">
                        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                        Add
                    </button>
                </form>
            </div>
        </div>

        <hr/>

        <div class="row">
            <div class="col-xs-8 col-xs-offset-2">
                <div class="row">
                    <div class="col-xs-4">
                        Click to vote
                    </div>
                </div>
                <div class="row top-buffer" ng-repeat="vote in votes.data">
                    <div class="col-xs-8">
                        <button class="btn btn-success text-left btn-block" ng-click="add(vote.key)">
                            <span class="pull-left">
                                {{vote.key}}
                            </span>
                            <span class="badge pull-right">
                                {{vote.value}} Votes
                            </span>
                        </button>
                    </div>
                    <div class="col-xs-4">
                        <button class="btn btn-danger pull-right btn-block" ng-click="remove(vote.key)">
                            <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
                            Remove
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Mettre à jour le fichier _Layout.cshtmlUpdate the _Layout.cshtml file

Ouvrez le fichier Views/Shared/_Layout.cshtml. Il s’agit de la disposition par défaut pour l’application ASP.NET.Open Views/Shared/_Layout.cshtml, the default layout for the ASP.NET app. Remplacez son contenu par la commande suivante, puis enregistrez vos modifications.Replace its contents with the following, then save your changes.

<!DOCTYPE html>
<html ng-app="VotingApp" xmlns:ng="https://angularjs.org">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>@ViewData["Title"]</title>

    <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet"/>
    <link href="~/css/site.css" rel="stylesheet"/>

</head>
<body>
<div class="container body-content">
    @RenderBody()
</div>

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<script src="~/js/site.js"></script>

@RenderSection("Scripts", required: false)
</body>
</html>

Mettre à jour le fichier VotingWeb.csUpdate the VotingWeb.cs file

Ouvrez le fichier VotingWeb.cs. Il crée le WebHost Core ASP.NET dans le service sans état à l’aide du serveur web WebListener.Open the VotingWeb.cs file, which creates the ASP.NET Core WebHost inside the stateless service using the WebListener web server.

Ajoutez la directive using System.Net.Http; au début du fichier.Add the using System.Net.Http; directive to the top of the file.

Remplacez la fonction CreateServiceInstanceListeners() par la commande suivante, puis enregistrez vos modifications.Replace the CreateServiceInstanceListeners() function with the following code, then save your changes.

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(
            serviceContext =>
                new KestrelCommunicationListener(
                    serviceContext,
                    "ServiceEndpoint",
                    (url, listener) =>
                    {
                        ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                        return new WebHostBuilder()
                            .UseKestrel()
                            .ConfigureServices(
                                services => services
                                    .AddSingleton<HttpClient>(new HttpClient())
                                    .AddSingleton<FabricClient>(new FabricClient())
                                    .AddSingleton<StatelessServiceContext>(serviceContext))
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseStartup<Startup>()
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                            .UseUrls(url)
                            .Build();
                    }))
    };
}

Ajoutez également le code suivant GetVotingDataServiceName méthode ci-dessous CreateServiceInstanceListeners(), puis enregistrez vos modifications.Also add the following GetVotingDataServiceName method below CreateServiceInstanceListeners(), then save your changes. GetVotingDataServiceName renvoie le nom du service lorsqu’il est interrogé.GetVotingDataServiceName returns the service name when polled.

internal static Uri GetVotingDataServiceName(ServiceContext context)
{
    return new Uri($"{context.CodePackageActivationContext.ApplicationName}/VotingData");
}

Ajouter le fichier VotesController.csAdd the VotesController.cs file

Ajoutez un contrôleur qui définit les actions de vote.Add a controller, which defines voting actions. Cliquez avec le bouton droit sur le dossier Contrôleurs et sélectionnez Ajouter -> Nouvel élément -> Visual C# -> ASP.NET Core -> Classe.Right-click on the Controllers folder, then select Add->New item->Visual C#->ASP.NET Core->Class. Nommez le fichier VotesController.cs et cliquez sur Ajouter.Name the file VotesController.cs, then click Add.

Remplacez le contenu du fichier VotesController.cs par la commande suivante, puis enregistrez vos modifications.Replace the VotesController.cs file contents with the following, then save your changes. Plus tard, dans Mettre à jour le fichier VotesController.cs, ce fichier est modifié pour lire et écrire des données de vote à partir du service principal.Later, in Update the VotesController.cs file, this file is modified to read and write voting data from the back-end service. Pour l’instant, le contrôleur renvoie des données de chaîne statique à la vue.For now, the controller returns static string data to the view.

namespace VotingWeb.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Fabric;
    using System.Fabric.Query;
    using System.Linq;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;

    [Produces("application/json")]
    [Route("api/Votes")]
    public class VotesController : Controller
    {
        private readonly HttpClient httpClient;

        public VotesController(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        // GET: api/Votes
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            List<KeyValuePair<string, int>> votes= new List<KeyValuePair<string, int>>();
            votes.Add(new KeyValuePair<string, int>("Pizza", 3));
            votes.Add(new KeyValuePair<string, int>("Ice cream", 4));

            return Json(votes);
        }
     }
}

Configurer le port d’écouteConfigure the listening port

Lorsque le service frontal VotingWeb est créé, Visual Studio sélectionne de manière aléatoire le port d’écoute du service.When the VotingWeb front-end service is created, Visual Studio randomly selects a port for the service to listen on. Le service VotingWeb joue le rôle de serveur frontal de cette application et accepte le trafic externe. Associez ce service à un port fixe et connu.The VotingWeb service acts as the front-end for this application and accepts external traffic, so let's bind that service to a fixed and well-know port. Le manifeste de service déclare les points de terminaison de service.The service manifest declares the service endpoints.

Dans l’Explorateur de solutions, ouvrez VotingWeb/PackageRoot/ServiceManifest.xml.In Solution Explorer, open VotingWeb/PackageRoot/ServiceManifest.xml. Recherchez l’élément Endpoint dans la section Resources, puis remplacez la valeur du port par 8080.Find the Endpoint element in the Resources section and change the Port value to 8080. Pour déployer et exécuter l’application localement, le port d’écoute de l’application doit être ouvert et disponible sur votre ordinateur.To deploy and run the application locally, the application listening port must be open and available on your computer.

<Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to 
           listen. Please note that if your service is partitioned, this port is shared with 
           replicas of different partitions that are placed in your code. -->
      <Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8080" />
    </Endpoints>
  </Resources>

Mettez également à jour la valeur de la propriété d’URL d’application dans le projet Voting, afin qu’un navigateur web s’ouvre sur le port adéquat lorsque vous effectuez le débogage de votre application.Also update the Application URL property value in the Voting project so a web browser opens to the correct port when you debug your application. Dans l’Explorateur de solutions, sélectionnez le projet Voting et définissez la propriété URL de l’application sur 8080.In Solution Explorer, select the Voting project and update the Application URL property to 8080.

Déployer et exécuter l’application Voting localementDeploy and run the Voting application locally

Vous pouvez maintenant continuer et exécuter l’application pour le débogage.You can now go ahead and run the Voting application for debugging. Dans Visual Studio, appuyez sur F5 pour déployer l’application sur votre cluster Service Fabric local en mode débogage.In Visual Studio, press F5 to deploy the application to your local Service Fabric cluster in debug mode. L’application échoue si vous n’avez pas précédemment ouvert Visual Studio en tant qu’administrateur.The application will fail if you didn't previously open Visual Studio as administrator.

Notes

La première fois que vous exécutez et déployez l’application localement, Visual Studio crée un cluster Service Fabric local pour le débogage.The first time you run and deploy the application locally, Visual Studio creates a local Service Fabric cluster for debugging. La création de cluster peut prendre un certain temps.Cluster creation may take some time. L’état de la création du cluster est affiché dans la fenêtre Sortie Visual Studio.The cluster creation status is displayed in the Visual Studio output window.

Une fois que l’application de vote a été déployée sur votre cluster Service Fabric local, votre application web s’ouvre automatiquement dans un onglet de navigateur et doit ressembler à ceci :After the Voting application has been deployed to your local Service Fabric cluster, your web app will open in a browser tab automatically and should look like this:

ASP.NET Core frontal

Pour arrêter le débogage de l’application, revenez à Visual Studio et appuyez sur Maj + F5.To stop debugging the application, go back to Visual Studio and press Shift+F5.

Ajouter un service principal avec état à votre applicationAdd a stateful back-end service to your application

Maintenant qu’un service API Web ASP.NET est exécuté dans l’application, ajoutez un service fiable avec état pour stocker des données dans l’application.Now that an ASP.NET Web API service is running in the application, go ahead and add a stateful reliable service to store some data in the application.

Service Fabric permet de stocker de manière cohérente et fiable vos données directement dans votre service à l’aide de collections fiables.Service Fabric allows you to consistently and reliably store your data right inside your service by using reliable collections. Les collections fiables sont un ensemble de classes de collections hautement disponibles et fiables avec lesquelles tous ceux qui ont utilisé les collections C# sont familiers.Reliable collections are a set of highly available and reliable collection classes that are familiar to anyone who has used C# collections.

Dans ce tutoriel, vous créez un service qui stocke une valeur de compteur dans une collection fiable.In this tutorial, you create a service which stores a counter value in a reliable collection.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur Services dans le projet d’application Voting et choisissez Ajouter > Nouveau service Service Fabric.In Solution Explorer, right-click Services within the Voting application project and choose Add -> New Service Fabric Service....

  2. Dans la boîte de dialogue Nouveau service Service Fabric, choisissez ASP.NET Core avec état, nommez le service VotingData, puis appuyez sur OK.In the New Service Fabric Service dialog, choose Stateful ASP.NET Core, name the service VotingData, then press OK.

    Une fois votre projet de service créé, votre application contient deux services.Once your service project is created, you have two services in your application. À mesure que vous continuez à développer votre application, vous pouvez ajouter d’autres services de la même façon.As you continue to build your application, you can add more services in the same way. Chacun peut être mis à niveau et faire l'objet d'un contrôle de version indépendamment.Each can be independently versioned and upgraded.

  3. La page suivante fournit un ensemble de modèles de projets ASP.NET Core.The next page provides a set of ASP.NET Core project templates. Pour ce tutoriel, sélectionnez API.For this tutorial, choose API.

    Visual Studio crée un projet de service VotingData et l’affiche dans l’Explorateur de solutions.Visual Studio creates the VotingData service project and displays it in Solution Explorer.

    Explorateur de solutions

Ajouter le fichier VoteDataController.csAdd the VoteDataController.cs file

Dans le projet VotingData, cliquez avec le bouton droit sur le dossier Contrôleurs et sélectionnez Ajouter -> Nouvel élément -> Classe.In the VotingData project, right-click on the Controllers folder, then select Add->New item->Class. Nommez le fichier VoteDataController.cs et cliquez sur Ajouter.Name the file VoteDataController.cs and click Add. Remplacez le contenu du fichier par la commande suivante, puis enregistrez vos modifications.Replace the file contents with the following, then save your changes.

namespace VotingData.Controllers
{
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.ServiceFabric.Data;
    using Microsoft.ServiceFabric.Data.Collections;

    [Route("api/[controller]")]
    public class VoteDataController : Controller
    {
        private readonly IReliableStateManager stateManager;

        public VoteDataController(IReliableStateManager stateManager)
        {
            this.stateManager = stateManager;
        }

        // GET api/VoteData
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            CancellationToken ct = new CancellationToken();

            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                Microsoft.ServiceFabric.Data.IAsyncEnumerable<KeyValuePair<string, int>> list = await votesDictionary.CreateEnumerableAsync(tx);

                Microsoft.ServiceFabric.Data.IAsyncEnumerator<KeyValuePair<string, int>> enumerator = list.GetAsyncEnumerator();

                List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();

                while (await enumerator.MoveNextAsync(ct))
                {
                    result.Add(enumerator.Current);
                }

                return this.Json(result);
            }
        }

        // PUT api/VoteData/name
        [HttpPut("{name}")]
        public async Task<IActionResult> Put(string name)
        {
            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await votesDictionary.AddOrUpdateAsync(tx, name, 1, (key, oldvalue) => oldvalue + 1);
                await tx.CommitAsync();
            }

            return new OkResult();
        }

        // DELETE api/VoteData/name
        [HttpDelete("{name}")]
        public async Task<IActionResult> Delete(string name)
        {
            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                if (await votesDictionary.ContainsKeyAsync(tx, name))
                {
                    await votesDictionary.TryRemoveAsync(tx, name);
                    await tx.CommitAsync();
                    return new OkResult();
                }
                else
                {
                    return new NotFoundResult();
                }
            }
        }
    }
}

Connecter les servicesConnect the services

Dans l’étape qui suit, connectez les deux services et faites en sorte que l’application web frontale obtienne et définisse les informations de vote à partir du service principal.In this next step, connect the two services and make the front-end Web application get and set voting information from the back-end service.

Service Fabric fournit une flexibilité complète sur votre façon de communiquer avec Reliable Services.Service Fabric provides complete flexibility in how you communicate with reliable services. Dans une même application, vous pouvez avoir des services qui sont accessibles via TCP,Within a single application, you might have services that are accessible via TCP. d’autres services accessibles via une API REST HTTP et encore d’autres services accessibles via des sockets web.Other services that might be accessible via an HTTP REST API and still other services could be accessible via web sockets. Pour obtenir des informations sur les options disponibles et leurs avantages/inconvénients respectifs, consultez Communication avec les services.For background on the options available and the tradeoffs involved, see Communicating with services.

Dans ce tutoriel, utilisez l’API web ASP.NET Core et le proxy inverse Service Fabric pour que le service web frontal VotingWeb puisse communiquer avec le service de données principal VotingWeb.This tutorial uses ASP.NET Core Web API and the Service Fabric reverse proxy so the VotingWeb front-end web service can communicate with the back-end VotingData service. Le proxy inverse est configuré par défaut pour utiliser le port 19081 et doit fonctionner pour ce tutoriel.The reverse proxy is configured by default to use port 19081 and should work for this tutorial. Le port du proxy inverse est défini dans le modèle Azure Resource Manager utilisé pour configurer le cluster.The reverse proxy port is set in the Azure Resource Manager template used to set up the cluster. Pour connaître le port utilisé, examinez le modèle de cluster dans la ressource Microsoft.ServiceFabric/clusters :To find which port is used, look in the cluster template in the Microsoft.ServiceFabric/clusters resource:

"nodeTypes": [
          {
            ...
            "httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
            "isPrimary": true,
            "vmInstanceCount": "[parameters('nt0InstanceCount')]",
            "reverseProxyEndpointPort": "[parameters('SFReverseProxyPort')]"
          }
        ],

Pour rechercher le port de proxy inverse utilisé dans votre cluster de développement local, examinez l’élément HttpApplicationGatewayEndpoint dans le manifeste de cluster Service Fabric local :To find the reverse proxy port used in your local development cluster, view the HttpApplicationGatewayEndpoint element in the local Service Fabric cluster manifest:

  1. Ouvrez une fenêtre de navigateur et accédez à http://localhost:19080 pour ouvrir l’outil Service Fabric Explorer.Open a browser window and navigate to http://localhost:19080 to open the Service Fabric Explorer tool.
  2. Sélectionnez Cluster -> Manifeste.Select Cluster -> Manifest.
  3. Notez l’élément de port HttpApplicationGatewayEndpoint.Make a note of the HttpApplicationGatewayEndpoint element port. Il doit s’agir par défaut de 19081.By default this should be 19081. Si tel n’est pas le cas, vous devez modifier le port dans la méthode GetProxyAddress du code VotesController.cs suivant.If it is not 19081, you will need to change the port in the GetProxyAddress method of the following VotesController.cs code.

Mettre à jour le fichier VotesController.csUpdate the VotesController.cs file

Dans le projet VotingWeb, ouvrez le fichier Controllers/VotesController.cs.In the VotingWeb project, open the Controllers/VotesController.cs file. Remplacez le contenu de définition de classe VotesController par la commande suivante, puis enregistrez vos modifications.Replace the VotesController class definition contents with the following, then save your changes. Si le port de proxy inverse découvert à l’étape précédente n’est pas 19081, modifiez le port utilisé dans la méthode GetProxyAddress en remplaçant la valeur 19081 par celle du port que vous avez découvert.If the reverse proxy port you discovered in the pervious step is not 19081, change the port used in the GetProxyAddress method from 19081 to the port that you discovered.

public class VotesController : Controller
{
    private readonly HttpClient httpClient;
    private readonly FabricClient fabricClient;
    private readonly StatelessServiceContext serviceContext;

    public VotesController(HttpClient httpClient, StatelessServiceContext context, FabricClient fabricClient)
    {
        this.fabricClient = fabricClient;
        this.httpClient = httpClient;
        this.serviceContext = context;
    }

    // GET: api/Votes
    [HttpGet("")]
    public async Task<IActionResult> Get()
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);

        ServicePartitionList partitions = await this.fabricClient.QueryManager.GetPartitionListAsync(serviceName);

        List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();

        foreach (Partition partition in partitions)
        {
            string proxyUrl =
                $"{proxyAddress}/api/VoteData?PartitionKey={((Int64RangePartitionInformation) partition.PartitionInformation).LowKey}&PartitionKind=Int64Range";

            using (HttpResponseMessage response = await this.httpClient.GetAsync(proxyUrl))
            {
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    continue;
                }

                result.AddRange(JsonConvert.DeserializeObject<List<KeyValuePair<string, int>>>(await response.Content.ReadAsStringAsync()));
            }
        }

        return this.Json(result);
    }

    // PUT: api/Votes/name
    [HttpPut("{name}")]
    public async Task<IActionResult> Put(string name)
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);
        long partitionKey = this.GetPartitionKey(name);
        string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";

        StringContent putContent = new StringContent($"{{ 'name' : '{name}' }}", Encoding.UTF8, "application/json");
        putContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        using (HttpResponseMessage response = await this.httpClient.PutAsync(proxyUrl, putContent))
        {
            return new ContentResult()
            {
                StatusCode = (int) response.StatusCode,
                Content = await response.Content.ReadAsStringAsync()
            };
        }
    }

    // DELETE: api/Votes/name
    [HttpDelete("{name}")]
    public async Task<IActionResult> Delete(string name)
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);
        long partitionKey = this.GetPartitionKey(name);
        string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";

        using (HttpResponseMessage response = await this.httpClient.DeleteAsync(proxyUrl))
        {
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                return this.StatusCode((int) response.StatusCode);
            }
        }

        return new OkResult();
    }


    /// <summary>
    /// Constructs a reverse proxy URL for a given service.
    /// Example: http://localhost:19081/VotingApplication/VotingData/
    /// </summary>
    /// <param name="serviceName"></param>
    /// <returns></returns>
    private Uri GetProxyAddress(Uri serviceName)
    {
        return new Uri($"http://localhost:19081{serviceName.AbsolutePath}");
    }

    /// <summary>
    /// Creates a partition key from the given name.
    /// Uses the zero-based numeric position in the alphabet of the first letter of the name (0-25).
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    private long GetPartitionKey(string name)
    {
        return Char.ToUpper(name.First()) - 'A';
    }
}

Guide de l’exemple d’application de voteWalk through the voting sample application

L’application de vote se compose de deux services :The voting application consists of two services:

  • Service frontal web (VotingWeb) : service frontal web ASP.NET Core qui fait office de page web et expose les API web pour communiquer avec le service principal.Web front-end service (VotingWeb)- An ASP.NET Core web front-end service, which serves the web page and exposes web APIs to communicate with the backend service.
  • Service principal (VotingData) : service web ASP.NET Core qui expose une API pour stocker les résultats de vote dans un dictionnaire fiable rendu persistant sur disque.Back-end service (VotingData)- An ASP.NET Core web service, which exposes an API to store the vote results in a reliable dictionary persisted on disk.

Diagramme de l’application

Lorsque vous votez dans l’application, les événements suivants se produisent :When you vote in the application the following events occur:

  1. Un JavaScript envoie la demande de vote à l’API web dans le service frontal web en tant que demande HTTP PUT.A JavaScript sends the vote request to the web API in the web front-end service as an HTTP PUT request.

  2. Le service frontal web utilise un proxy pour localiser et transférer une demande HTTP PUT au service principal.The web front-end service uses a proxy to locate and forward an HTTP PUT request to the back-end service.

  3. Le service principal accepte la demande entrante, puis stocke le résultat mis à jour dans un dictionnaire fiable, qui est répliqué sur plusieurs nœuds au sein du cluster et rendu persistant sur disque.The back-end service takes the incoming request, and stores the updated result in a reliable dictionary, which gets replicated to multiple nodes within the cluster and persisted on disk. Toutes les données de l’application étant stockées dans le cluster, aucune base de données n’est nécessaire.All the application's data is stored in the cluster, so no database is needed.

Déboguer dans Visual StudioDebug in Visual Studio

Lors du débogage d’application dans Visual Studio, vous utilisez un cluster de développement Service Fabric local.When debugging application in Visual Studio, you are using a local Service Fabric development cluster. Vous avez la possibilité d’adapter votre expérience de débogage à votre scénario.You have the option to adjust your debugging experience to your scenario. Dans cette application, stockez les données dans le service principal à l’aide d’un dictionnaire fiable.In this application, store data in the back-end service using a reliable dictionary. Visual Studio supprime l’application par défaut lorsque vous arrêtez le débogueur.Visual Studio removes the application per default when you stop the debugger. La suppression de l’application a pour effet de supprimer également les données dans le service principal.Removing the application causes the data in the back-end service to also be removed. Pour rendre les données persistantes entre les sessions de débogage, vous pouvez modifier le Mode de débogage de l'application en tant que propriété sur le projet Voting dans Visual Studio.To persist the data between debugging sessions, you can change the Application Debug Mode as a property on the Voting project in Visual Studio.

Pour examiner ce qui se produit dans le code, procédez comme suit :To look at what happens in the code, complete the following steps:

  1. Ouvrez le fichier VotingWeb\VotesController.cs et définissez un point d’arrêt dans la méthode Put de l’API web (ligne 72).Open the VotingWeb\VotesController.cs file and set a breakpoint in the web API's Put method (line 72).

  2. Ouvrez le fichier VotingData\VoteDataController.cs et définissez un point d’arrêt dans la méthode Put de l’API web (ligne 54).Open the VotingData\VoteDataController.cs file and set a breakpoint in this web API's Put method (line 54).

  3. Appuyez sur F5 pour exécuter l'application en mode débogage.Press F5 to start the application in debug mode.

  4. Revenez en arrière dans le navigateur, puis cliquez sur une option de vote ou ajoutez une nouvelle option de vote.Go back to the browser and click a voting option or add a new voting option. Vous avez atteint le premier point d’arrêt dans le contrôleur d’api du service frontal web.You hit the first breakpoint in the web front-end's api controller.

    1. Il s’agit de l’emplacement où le JavaScript dans le navigateur envoie une demande au contrôleur d’API web dans le service frontal.This is where the JavaScript in the browser sends a request to the web API controller in the front-end service.

      Ajouter un service de vote frontal

    2. Tout d’abord, créez l’URL du ReverseProxy pour le service principal (1) .First construct the URL to the ReverseProxy for the back-end service (1).

    3. Ensuite, envoyez la requête HTTP PUT au ReverseProxy (2) .Then send the HTTP PUT Request to the ReverseProxy (2).

    4. Pour finir, renvoyez la réponse du service principal au client (3) .Finally the return the response from the back-end service to the client (3).

  5. Appuyez sur F5 pour continuer.Press F5 to continue.

    1. Vous êtes à présent au point d’arrêt dans le service principal.You are now at the break point in the back-end service.

      Ajouter un service de vote principal

    2. Dans la première ligne de la méthode (1) , utilisez le StateManager pour obtenir ou ajouter un dictionnaire fiable nommé counts.In the first line in the method (1) use the StateManager to get or add a reliable dictionary called counts.

    3. Toutes les interactions avec des valeurs d’un dictionnaire fiable requièrent une transaction. Cette instruction using (2) crée cette transaction.All interactions with values in a reliable dictionary require a transaction, this using statement (2) creates that transaction.

    4. Dans la transaction, mettez à jour la valeur de la clé appropriée pour l’option de vote et validez l’opération (3) .In the transaction, update the value of the relevant key for the voting option and commits the operation (3). Lorsque la méthode commit retourne des données, celles-ci sont mises à jour dans le dictionnaire et répliquées sur d’autres nœuds du cluster.Once the commit method returns, the data is updated in the dictionary and replicated to other nodes in the cluster. Les données sont à présent stockées en sécurité dans le cluster, et le service principal peut basculer vers d’autres nœuds, tout en gardant les données disponibles.The data is now safely stored in the cluster, and the back-end service can fail over to other nodes, still having the data available.

  6. Appuyez sur F5 pour continuer.Press F5 to continue.

Pour arrêter la session de débogage, appuyez sur Maj+F5.To stop the debugging session, press Shift+F5.

Étapes suivantesNext steps

Dans cette partie du tutoriel, vous avez appris à :In this part of the tutorial, you learned how to:

  • Créer un service API Web ASP.NET Core en tant que service fiable avec étatCreate an ASP.NET Core Web API service as a stateful reliable service
  • Créer un service d’application Web ASP.NET Core en tant que service web sans étatCreate an ASP.NET Core Web Application service as a stateless web service
  • Utiliser le proxy inverse pour communiquer avec le service avec étatUse the reverse proxy to communicate with the stateful service

Passez au tutoriel suivant :Advance to the next tutorial: