Didacticiel : appeler une API Web ASP.NET Core avec JavaScriptTutorial: Call an ASP.NET Core web API with JavaScript

De Rick AndersonBy Rick Anderson

Ce tutoriel montre comment appeler une API web ASP.NET Core avec JavaScript à l’aide de l’API Fetch.This tutorial shows how to call an ASP.NET Core web API with JavaScript, using the Fetch API.

Pour ASP.NET Core 2.2, consultez la version 2.2 de Appeler l’API web avec JavaScript.For ASP.NET Core 2.2, see the 2.2 version of Call the web API with JavaScript.

Conditions préalables requisesPrerequisites

Appelez l’API web avec JavaScriptCall the web API with JavaScript

Dans cette section, vous allez ajouter une page HTML contenant des formulaires permettant de créer et de gérer des éléments de tâche.In this section, you'll add an HTML page containing forms for creating and managing to-do items. Des gestionnaires d’événements sont joints aux éléments de la page.Event handlers are attached to elements on the page. Les gestionnaires d’événements génèrent des requêtes HTTP pour les méthodes d’action de l’API web.The event handlers result in HTTP requests to the web API's action methods. La fonction fetch de l’API Fetch lance chaque requête HTTP.The Fetch API's fetch function initiates each HTTP request.

La fonction fetch retourne un objet promesse , qui contient une réponse http représentée sous la forme d’un objet Response.The fetch function returns a Promise object, which contains an HTTP response represented as a Response object. Un modèle courant consiste à extraire le corps de réponse JSON en appelant la fonction json sur l'objet Response.A common pattern is to extract the JSON response body by invoking the json function on the Response object. JavaScript met à jour la page avec les détails de la réponse de l’API Web.JavaScript updates the page with the details from the web API's response.

L'appel fetch le plus simple accepte un seul paramètre représentant l’itinéraire.The simplest fetch call accepts a single parameter representing the route. Un deuxième paramètre, connu sous le nom d’objet init, est facultatif.A second parameter, known as the init object, is optional. init est utilisé pour configurer la requête HTTP.init is used to configure the HTTP request.

  1. Configurez l’application pour traiter les fichiers statiques et activer le mappage du fichier par défaut.Configure the app to serve static files and enable default file mapping. Le code en surbrillance suivant est nécessaire dans la méthode Configure de Startup.cs :The following highlighted code is needed in the Configure method of Startup.cs:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseDefaultFiles();
        app.UseStaticFiles();
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    
  2. Créez un dossier wwwroot dans la racine du projet.Create a wwwroot folder in the project root.

  3. Créez un dossier js à l’intérieur du dossier wwwroot .Create a js folder inside of the wwwroot folder.

  4. Ajoutez un fichier HTML nommé index. html au dossier wwwroot .Add an HTML file named index.html to the wwwroot folder. Remplacez le contenu de index. html par le balisage suivant :Replace the contents of index.html with the following markup:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>To-do CRUD</title>
        <link rel="stylesheet" href="css/site.css" />
    </head>
    <body>
        <h1>To-do CRUD</h1>
        <h3>Add</h3>
        <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
            <input type="text" id="add-name" placeholder="New to-do">
            <input type="submit" value="Add">
        </form>
    
        <div id="editForm">
            <h3>Edit</h3>
            <form action="javascript:void(0);" onsubmit="updateItem()">
                <input type="hidden" id="edit-id">
                <input type="checkbox" id="edit-isComplete">
                <input type="text" id="edit-name">
                <input type="submit" value="Save">
                <a onclick="closeInput()" aria-label="Close">&#10006;</a>
            </form>
        </div>
    
        <p id="counter"></p>
    
        <table>
            <tr>
                <th>Is Complete?</th>
                <th>Name</th>
                <th></th>
                <th></th>
            </tr>
            <tbody id="todos"></tbody>
        </table>
    
        <script src="js/site.js" asp-append-version="true"></script>
        <script type="text/javascript">
            getItems();
        </script>
    </body>
    </html>
    
  5. Ajoutez un fichier JavaScript nommé site. js au dossier wwwroot/js .Add a JavaScript file named site.js to the wwwroot/js folder. Remplacez le contenu de site. js par le code suivant :Replace the contents of site.js with the following code:

    const uri = 'api/TodoItems';
    let todos = [];
    
    function getItems() {
      fetch(uri)
        .then(response => response.json())
        .then(data => _displayItems(data))
        .catch(error => console.error('Unable to get items.', error));
    }
    
    function addItem() {
      const addNameTextbox = document.getElementById('add-name');
    
      const item = {
        isComplete: false,
        name: addNameTextbox.value.trim()
      };
    
      fetch(uri, {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item)
      })
        .then(response => response.json())
        .then(() => {
          getItems();
          addNameTextbox.value = '';
        })
        .catch(error => console.error('Unable to add item.', error));
    }
    
    function deleteItem(id) {
      fetch(`${uri}/${id}`, {
        method: 'DELETE'
      })
      .then(() => getItems())
      .catch(error => console.error('Unable to delete item.', error));
    }
    
    function displayEditForm(id) {
      const item = todos.find(item => item.id === id);
      
      document.getElementById('edit-name').value = item.name;
      document.getElementById('edit-id').value = item.id;
      document.getElementById('edit-isComplete').checked = item.isComplete;
      document.getElementById('editForm').style.display = 'block';
    }
    
    function updateItem() {
      const itemId = document.getElementById('edit-id').value;
      const item = {
        id: parseInt(itemId, 10),
        isComplete: document.getElementById('edit-isComplete').checked,
        name: document.getElementById('edit-name').value.trim()
      };
    
      fetch(`${uri}/${itemId}`, {
        method: 'PUT',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item)
      })
      .then(() => getItems())
      .catch(error => console.error('Unable to update item.', error));
    
      closeInput();
    
      return false;
    }
    
    function closeInput() {
      document.getElementById('editForm').style.display = 'none';
    }
    
    function _displayCount(itemCount) {
      const name = (itemCount === 1) ? 'to-do' : 'to-dos';
    
      document.getElementById('counter').innerText = `${itemCount} ${name}`;
    }
    
    function _displayItems(data) {
      const tBody = document.getElementById('todos');
      tBody.innerHTML = '';
    
      _displayCount(data.length);
    
      const button = document.createElement('button');
    
      data.forEach(item => {
        let isCompleteCheckbox = document.createElement('input');
        isCompleteCheckbox.type = 'checkbox';
        isCompleteCheckbox.disabled = true;
        isCompleteCheckbox.checked = item.isComplete;
    
        let editButton = button.cloneNode(false);
        editButton.innerText = 'Edit';
        editButton.setAttribute('onclick', `displayEditForm(${item.id})`);
    
        let deleteButton = button.cloneNode(false);
        deleteButton.innerText = 'Delete';
        deleteButton.setAttribute('onclick', `deleteItem(${item.id})`);
    
        let tr = tBody.insertRow();
        
        let td1 = tr.insertCell(0);
        td1.appendChild(isCompleteCheckbox);
    
        let td2 = tr.insertCell(1);
        let textNode = document.createTextNode(item.name);
        td2.appendChild(textNode);
    
        let td3 = tr.insertCell(2);
        td3.appendChild(editButton);
    
        let td4 = tr.insertCell(3);
        td4.appendChild(deleteButton);
      });
    
      todos = data;
    }
    

Vous devrez peut-être changer les paramètres de lancement du projet ASP.NET Core pour tester la page HTML localement :A change to the ASP.NET Core project's launch settings may be required to test the HTML page locally:

  1. Ouvrez Properties\launchSettings.json.Open Properties\launchSettings.json.
  2. Supprimez la propriété launchUrl pour forcer l’utilisation du fichier index.html (fichier par défaut du projet) à l’ouverture de l’application.Remove the launchUrl property to force the app to open at index.html—the project's default file.

Cet exemple appelle toutes les méthodes CRUD de l’API web.This sample calls all of the CRUD methods of the web API. Les explications suivantes traitent des demandes de l’API web.Following are explanations of the web API requests.

Obtenir une liste de tâchesGet a list of to-do items

Dans le code suivant, une requête HTTP GET est envoyée à l'itinéraire api/TodoItems :In the following code, an HTTP GET request is sent to the api/TodoItems route:

fetch(uri)
  .then(response => response.json())
  .then(data => _displayItems(data))
  .catch(error => console.error('Unable to get items.', error));

Quand l’API web retourne un code d’état de réussite, la fonction _displayItems est appelée.When the web API returns a successful status code, the _displayItems function is invoked. Chaque élément de tâche du paramètre de tableau accepté par _displayItems est ajouté à une table avec les boutons Modifier et Supprimer.Each to-do item in the array parameter accepted by _displayItems is added to a table with Edit and Delete buttons. Si la demande de l’API Web échoue, une erreur est consignée dans la console du navigateur.If the web API request fails, an error is logged to the browser's console.

Ajouter une tâcheAdd a to-do item

Dans le code suivant :In the following code:

  • Une variable item est déclarée pour construire une représentation littérale d’objet de l’élément de tâche.An item variable is declared to construct an object literal representation of the to-do item.
  • Une requête Fetch est configurée avec les options suivantes :A Fetch request is configured with the following options:
    • method— spécifie le verbe d’action POST HTTP.method—specifies the POST HTTP action verb.
    • body— spécifie la représentation JSON du corps de la demande.body—specifies the JSON representation of the request body. Le JSON est généré en passant le littéral d’objet stocké dans item à la fonction JSON. stringify.The JSON is produced by passing the object literal stored in item to the JSON.stringify function.
    • headers— spécifie les en-têtes de requête HTTP Accept et Content-Type.headers—specifies the Accept and Content-Type HTTP request headers. Les deux en-têtes sont définies sur application/json pour spécifier le type de média respectivement reçu et envoyé.Both headers are set to application/json to specify the media type being received and sent, respectively.
  • Une requête HTTP POST est envoyée à l’itinéraire api/TodoItems.An HTTP POST request is sent to the api/TodoItems route.
function addItem() {
  const addNameTextbox = document.getElementById('add-name');

  const item = {
    isComplete: false,
    name: addNameTextbox.value.trim()
  };

  fetch(uri, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(item)
  })
    .then(response => response.json())
    .then(() => {
      getItems();
      addNameTextbox.value = '';
    })
    .catch(error => console.error('Unable to add item.', error));
}

Quand l’API web retourne un code d’état de réussite, la fonction getItems est appelée pour mettre à jour la table HTML.When the web API returns a successful status code, the getItems function is invoked to update the HTML table. Si la demande de l’API Web échoue, une erreur est consignée dans la console du navigateur.If the web API request fails, an error is logged to the browser's console.

Mettre à jour une tâcheUpdate a to-do item

La mise à jour d’un élément de tâche est semblable à l’ajout d’un élément. Toutefois, il y a deux différences importantes :Updating a to-do item is similar to adding one; however, there are two significant differences:

  • L’itinéraire est suivi de l’identificateur unique de l’élément à mettre à jour.The route is suffixed with the unique identifier of the item to update. Par exemple, api/TodoItems/1.For example, api/TodoItems/1.
  • Le verbe d’action HTTP est PUT, comme indiqué par l’option method.The HTTP action verb is PUT, as indicated by the method option.
fetch(`${uri}/${itemId}`, {
  method: 'PUT',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(item)
})
.then(() => getItems())
.catch(error => console.error('Unable to update item.', error));

Supprimer une tâcheDelete a to-do item

Pour supprimer un élément de tâche, définissez l’option de la demande method sur DELETE et spécifiez l’identificateur unique de l’élément dans l’URL.To delete a to-do item, set the request's method option to DELETE and specify the item's unique identifier in the URL.

fetch(`${uri}/${id}`, {
  method: 'DELETE'
})
.then(() => getItems())
.catch(error => console.error('Unable to delete item.', error));

Passez au tutoriel suivant pour apprendre à générer des pages d’aide d’API web :Advance to the next tutorial to learn how to generate web API help pages: