Delen via


Zelfstudie: Een ASP.NET Core-web-API aanroepen met JavaScript

Door Rick Anderson

Deze zelfstudie laat zien hoe u een ASP.NET Core-web-API aanroept met JavaScript, met behulp van de Fetch API.

Voorwaarden

De web-API aanroepen met JavaScript

In deze sectie voegt u een HTML-pagina toe met formulieren voor het maken en beheren van to-do items. Gebeurtenishandlers worden gekoppeld aan elementen op de pagina. De gebeurtenis-handlers resulteren in HTTP-aanvragen voor de actiemethoden van de web-API. De fetch-functie van de Fetch-API initieert elke HTTP-aanvraag.

De functie fetch retourneert een Promise-object, dat een HTTP-antwoord bevat dat wordt weergegeven als een Response-object. Een veelvoorkomend patroon is het extraheren van de hoofdtekst van het JSON-antwoord door de functie json aan te roepen op het Response-object. JavaScript werkt de pagina bij met de details van het antwoord van de web-API.

De eenvoudigste fetch aanroep accepteert één parameter die de route vertegenwoordigt. Een tweede parameter, ook wel het init-object genoemd, is optioneel. init wordt gebruikt om de HTTP-aanvraag te configureren.

  1. Configureer de app voor het van statische bestanden en standaardbestandstoewijzing inschakelen. De volgende gemarkeerde code is nodig in Program.cs:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddDbContext<TodoContext>(opt =>
    opt.UseInMemoryDatabase("TodoList"));

var app = builder.Build();

if (builder.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
  1. Maak een map wwwroot in de hoofdmap van het project.

  2. Maak een css- map in de map wwwroot.

  3. Maak een js- map in de map wwwroot.

  4. Voeg een HTML-bestand met de naam index.html toe aan de map wwwroot. Vervang de inhoud van index.html door de volgende markeringen:

    <!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. Voeg een CSS-bestand met de naam site.css toe aan de map wwwroot/ css. Vervang de inhoud van site.css door de volgende stijlen:

    input[type='submit'], button, [aria-label] {
        cursor: pointer;
    }
    
    #editForm {
        display: none;
    }
    
    table {
        font-family: Arial, sans-serif;
        border: 1px solid;
        border-collapse: collapse;
    }
    
    th {
        background-color: #f8f8f8;
        padding: 5px;
    }
    
    td {
        border: 1px solid;
        padding: 5px;
    }
    
  6. Voeg een JavaScript-bestand met de naam site.js toe aan de map wwwroot/js. Vervang de inhoud van site.js door de volgende 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;
    }
    

Een wijziging in de startinstellingen van het ASP.NET Core-project kan nodig zijn om de HTML-pagina lokaal te testen:

  1. Open eigenschappen\launchSettings.jsop.
  2. Verwijder de eigenschap launchUrl om af te dwingen dat de app wordt geopend op index.html: het standaardbestand van het project.

In dit voorbeeld worden alle CRUD-methoden van de web-API aangeroepen. Hieronder volgen uitleg van de web-API-aanvragen.

Een lijst met to-do items ophalen

In de volgende code wordt een HTTP GET-aanvraag verzonden naar de API/todoitems route:

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

Wanneer de web-API een geslaagde statuscode retourneert, wordt de _displayItems-functie aangeroepen. Elk to-do item in de matrixparameter die door _displayItems wordt geaccepteerd, wordt toegevoegd aan een tabel met knoppen bewerken en verwijderen. Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item toevoegen

In de volgende code:

  • Een item variabele wordt gedeclareerd om een letterlijke objectweergave van het to-do item te maken.
  • Een ophaalaanvraag is geconfigureerd met de volgende opties:
    • method—specificeert het HTTP-actie werkwoord POST.
    • body: hiermee geeft u de JSON-weergave van de aanvraagbody op. De JSON wordt geproduceerd door het letterlijke object dat is opgeslagen in item door te geven aan de JSON.stringify functie.
    • headers: hiermee geeft u de Accept en Content-Type HTTP-aanvraagheaders op. Beide headers zijn ingesteld op application/json om respectievelijk het mediatype op te geven dat wordt ontvangen en verzonden.
  • Er wordt een HTTP POST-aanvraag verzonden naar de 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));
}

Wanneer de web-API een geslaagde statuscode retourneert, wordt de getItems functie aangeroepen om de HTML-tabel bij te werken. Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item bijwerken

Het bijwerken van een to-do item lijkt op het toevoegen van een item; er zijn echter twee belangrijke verschillen:

  • De route wordt voorzien van een achtervoegsel met de unieke ID van het item dat moet worden bijgewerkt. Bijvoorbeeld api/todoitems/1.
  • Het HTTP-actiewoord is PUT, zoals aangegeven door de optie method.
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));

Een to-do-item verwijderen

Als u een to-do item wilt verwijderen, stelt u de method optie van de aanvraag in op DELETE en geeft u de unieke id van het item op in de URL.

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

Ga naar de volgende zelfstudie voor meer informatie over het genereren van helppagina's voor web-API's:

Deze zelfstudie laat zien hoe u een ASP.NET Core-web-API aanroept met JavaScript, met behulp van de Fetch API.

Voorwaarden

De web-API aanroepen met JavaScript

In deze sectie voegt u een HTML-pagina toe met formulieren voor het maken en beheren van to-do items. Gebeurtenishandlers worden verbonden aan elementen op de pagina. De gebeurtenis-handlers resulteren in HTTP-aanvragen voor de actiemethoden van de web-API. De fetch-functie van de Fetch-API initieert elke HTTP-aanvraag.

De functie fetch retourneert een Promise-object, dat een HTTP-antwoord bevat dat wordt weergegeven als een Response-object. Een veelvoorkomend patroon is het extraheren van de hoofdtekst van het JSON-antwoord door de functie json aan te roepen op het Response-object. JavaScript werkt de pagina bij met de details van het antwoord van de web-API.

De eenvoudigste fetch aanroep accepteert één parameter die de route vertegenwoordigt. Een tweede parameter, ook wel het init-object genoemd, is optioneel. init wordt gebruikt om de HTTP-aanvraag te configureren.

  1. Configureer de app voor het van statische bestanden en standaardbestandstoewijzing inschakelen. De volgende gemarkeerde code is nodig in de Configure methode van 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. Maak een map wwwroot in de hoofdmap van het project.

  3. Maak een css- map in de map wwwroot.

  4. Maak een js- map in de map wwwroot.

  5. Voeg een HTML-bestand met de naam index.html toe aan de map wwwroot. Vervang de inhoud van index.html door de volgende markeringen:

    <!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>
    
  6. Voeg een CSS-bestand met de naam site.css toe aan de map wwwroot/ css. Vervang de inhoud van site.css door de volgende stijlen:

    input[type='submit'], button, [aria-label] {
        cursor: pointer;
    }
    
    #editForm {
        display: none;
    }
    
    table {
        font-family: Arial, sans-serif;
        border: 1px solid;
        border-collapse: collapse;
    }
    
    th {
        background-color: #f8f8f8;
        padding: 5px;
    }
    
    td {
        border: 1px solid;
        padding: 5px;
    }
    
  7. Voeg een JavaScript-bestand met de naam site.js toe aan de map wwwroot/js. Vervang de inhoud van site.js door de volgende 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;
    }
    

Een wijziging in de startinstellingen van het ASP.NET Core-project kan nodig zijn om de HTML-pagina lokaal te testen:

  1. Open de eigenschappen\launchSettings.jsop.
  2. Verwijder de eigenschap launchUrl om af te dwingen dat de app wordt geopend op index.html: het standaardbestand van het project.

In dit voorbeeld worden alle CRUD-methoden van de web-API aangeroepen. Hieronder volgen uitleg van de web-API-aanvragen.

Een lijst met to-do items ophalen

In de volgende code wordt een HTTP GET-aanvraag verzonden naar de API/todoitems route:

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

Wanneer de web-API een geslaagde statuscode retourneert, wordt de _displayItems-functie aangeroepen. Elk to-do item in de matrixparameter die door _displayItems wordt geaccepteerd, wordt toegevoegd aan een tabel met knoppen bewerken en verwijderen. Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item toevoegen

In de volgende code:

  • Een item variabele wordt gedeclareerd om een letterlijke objectweergave van het to-do item te maken.
  • Een ophaalaanvraag is geconfigureerd met de volgende opties:
    • method— specificeert de POST HTTP-actiewoord.
    • body: hiermee geeft u de JSON-weergave van de aanvraagbody op. De JSON wordt geproduceerd door het letterlijke object dat is opgeslagen in item door te geven aan de JSON.stringify functie.
    • headers: hiermee geeft u de Accept en Content-Type HTTP-aanvraagheaders op. Beide headers zijn ingesteld op application/json om respectievelijk het mediatype op te geven dat wordt ontvangen en verzonden.
  • Er wordt een HTTP POST-aanvraag verzonden naar de 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));
}

Wanneer de web-API een geslaagde statuscode retourneert, wordt de getItems functie aangeroepen om de HTML-tabel bij te werken. Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item bijwerken

Het bijwerken van een to-do item lijkt op het toevoegen van een item; er zijn echter twee belangrijke verschillen:

  • De route krijgt als achtervoegsel de unieke identificatie van het item dat moet worden bijgewerkt. Bijvoorbeeld api/todoitems/1.
  • Het HTTP-actiewoord is PUT, zoals aangegeven door de optie method.
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));

Een to-do-item verwijderen

Als u een to-do item wilt verwijderen, stelt u de method optie van de aanvraag in op DELETE en geeft u de unieke id van het item op in de URL.

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

Ga naar de volgende zelfstudie voor meer informatie over het genereren van helppagina's voor web-API's:

Deze zelfstudie laat zien hoe u een ASP.NET Core-web-API aanroept met JavaScript, met behulp van de Fetch API.

Voorwaarden

De web-API aanroepen met JavaScript

In deze sectie voegt u een HTML-pagina toe met formulieren voor het maken en beheren van to-do items. Gebeurtenishandlers worden gekoppeld aan elementen op de pagina. De gebeurtenis-handlers resulteren in HTTP-aanvragen voor de actiemethoden van de web-API. De fetch-functie van de Fetch-API initieert elke HTTP-aanvraag.

De functie fetch retourneert een Promise-object, dat een HTTP-antwoord bevat dat wordt weergegeven als een Response-object. Een veelvoorkomend patroon is het extraheren van de hoofdtekst van het JSON-antwoord door de functie json aan te roepen op het Response-object. JavaScript werkt de pagina bij met de details van het antwoord van de web-API.

De eenvoudigste fetch aanroep accepteert één parameter die de route vertegenwoordigt. Een tweede parameter, ook wel het init-object genoemd, is optioneel. init wordt gebruikt om de HTTP-aanvraag te configureren.

  1. Configureer de app voor het van statische bestanden en standaardbestandstoewijzing inschakelen. De volgende gemarkeerde code is nodig in Program.cs:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddDbContext<TodoContext>(opt =>
    opt.UseInMemoryDatabase("TodoList"));

var app = builder.Build();

if (builder.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
  1. Maak een map wwwroot in de hoofdmap van het project.

  2. Maak een css- map in de map wwwroot.

  3. Maak een js- map in de map wwwroot.

  4. Voeg een HTML-bestand met de naam index.html toe aan de map wwwroot. Vervang de inhoud van index.html door de volgende markeringen:

    <!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. Voeg een CSS-bestand met de naam site.css toe aan de map wwwroot/ css. Vervang de inhoud van site.css door de volgende stijlen:

    input[type='submit'], button, [aria-label] {
        cursor: pointer;
    }
    
    #editForm {
        display: none;
    }
    
    table {
        font-family: Arial, sans-serif;
        border: 1px solid;
        border-collapse: collapse;
    }
    
    th {
        background-color: #f8f8f8;
        padding: 5px;
    }
    
    td {
        border: 1px solid;
        padding: 5px;
    }
    
  6. Voeg een JavaScript-bestand met de naam site.js toe aan de map wwwroot/js. Vervang de inhoud van site.js door de volgende 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;
    }
    

Een wijziging in de startinstellingen van het ASP.NET Core-project kan nodig zijn om de HTML-pagina lokaal te testen:

  1. Open eigenschappen\launchSettings.jsop.
  2. Verwijder de eigenschap launchUrl om af te dwingen dat de app wordt geopend op index.html: het standaardbestand van het project.

In dit voorbeeld worden alle CRUD-methoden van de web-API aangeroepen. Hieronder volgen uitleg van de web-API-aanvragen.

Een lijst met to-do items ophalen

In de volgende code wordt een HTTP GET-aanvraag verzonden naar de API/todoitems route:

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

Wanneer de web-API een geslaagde statuscode retourneert, wordt de _displayItems-functie aangeroepen. Elk to-do item in de parameterarray die door _displayItems wordt geaccepteerd, wordt toegevoegd aan een tabel met de knoppen Bewerken en Verwijderen . Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item toevoegen

In de volgende code:

  • Een item variabele wordt gedeclareerd om een letterlijke objectweergave van het to-do item te maken.
  • Een ophaalaanvraag is geconfigureerd met de volgende opties:
    • method, hiermee specificeert u het HTTP-actie-werkwoord POST.
    • body: hiermee geeft u de JSON-weergave van de aanvraagbody op. De JSON wordt geproduceerd door het letterlijke object dat is opgeslagen in item door te geven aan de JSON.stringify functie.
    • headers: hiermee geeft u de Accept en Content-Type HTTP-aanvraagheaders op. Beide headers zijn ingesteld op application/json om respectievelijk het mediatype op te geven dat wordt ontvangen en verzonden.
  • Er wordt een HTTP POST-aanvraag verzonden naar de 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));
}

Wanneer de web-API een geslaagde statuscode retourneert, wordt de getItems functie aangeroepen om de HTML-tabel bij te werken. Als de web-API-aanvraag mislukt, wordt een fout vastgelegd in de console van de browser.

Een to-do-item bijwerken

Het bijwerken van een to-do item lijkt op het toevoegen van een item; er zijn echter twee belangrijke verschillen:

  • De route wordt voorzien van de unieke identificatie van het item dat bijgewerkt moet worden. Bijvoorbeeld api/todoitems/1.
  • Het HTTP-actiewoord is PUT, zoals aangegeven door de optie method.
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));

Een to-do-item verwijderen

Als u een to-do item wilt verwijderen, stelt u de method optie van de aanvraag in op DELETE en geeft u de unieke id van het item op in de URL.

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

Ga naar de volgende zelfstudie voor meer informatie over het genereren van helppagina's voor web-API's: