Esercitazione: Chiamare un'API Web ASP.NET Core con JavaScript

Di Rick Anderson

Questa esercitazione illustra come chiamare un'API Web ASP.NET Core con JavaScript usando l'API Fetch.

Prerequisiti

Chiamare l'API Web con JavaScript

In questa sezione, aggiungerai una pagina HTML contenente i moduli per creare e gestire le attività. Agli elementi della pagina vengono associati gestori eventi. I gestori eventi generano richieste HTTP ai metodi di azione dell'API Web. La funzione fetch dell'API Fetch avvia ogni richiesta HTTP.

La funzione fetch restituisce un oggetto Promise che contiene una risposta HTTP rappresentata come oggetto Response. Un modello comune consiste nell'estrarre il corpo della risposta JSON richiamando la funzione json per l'oggetto Response. JavaScript aggiorna la pagina con i dettagli della risposta dell'API Web.

La chiamata fetch più semplice accetta un solo parametro che rappresenta la route. Un secondo parametro, noto come oggetto init, è facoltativo. init viene usato per configurare la richiesta HTTP.

  1. Configurare l'app in modo che gestisca i file statici e consenta il mapping di file predefinito. Il codice evidenziato seguente è necessario 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. Creare una cartella wwwroot nella radice del progetto.

  2. Creare una cartella css all'interno della cartella wwwroot .

  3. Creare una cartella js all'interno della cartella wwwroot .

  4. Aggiungere un file HTML denominato index.html alla cartella wwwroot . Sostituire il contenuto di index.html con il markup seguente:

    <!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. Aggiungere un file CSS denominato site.css alla cartella wwwroot/css . Sostituire il contenuto di site.css con gli stili seguenti:

    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. Aggiungere un file JavaScript denominato site.js alla cartella wwwroot/js . Sostituire il contenuto di site.js con il codice seguente:

    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;
    }
    

Per testare la pagina HTML in locale, potrebbe essere necessaria una modifica alle impostazioni di avvio del progetto ASP.NET Core:

  1. Aprire Properties\launchSettings.json.
  2. Rimuovere la proprietà launchUrl per fare in modo che l'app si apra su index.html—il file predefinito del progetto.

In questo esempio vengono chiamati tutti i metodi CRUD dell'API Web. Di seguito sono disponibili spiegazioni per le richieste dell'API Web.

Ottieni un elenco di attività da svolgere

Nel codice seguente viene inviata una richiesta HTTP GET alla route api/todoitems :

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

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene chiamata la funzione _displayItems. Ogni elemento dell'elenco delle attività nel parametro array accettato da _displayItems viene aggiunto a una tabella con i pulsanti Edit e Delete. Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiungi un'attività da fare

Nel codice seguente:

  • Viene dichiarata una variabile item per costruire una rappresentazione letterale di un oggetto dell'elemento da fare.
  • Una richiesta di recupero viene configurata con le opzioni seguenti:
    • method: specifica il verbo di azione HTTP POST.
    • body: specifica la rappresentazione JSON del corpo della richiesta. Il codice JSON viene prodotto passando il valore letterale dell'oggetto archiviato in item alla funzione JSON.stringify.
    • headers: specifica le intestazioni Accept e Content-Type della richiesta HTTP. Entrambe le intestazioni sono impostate su application/json per specificare rispettivamente il tipo di contenuto ricevuto e quello inviato.
  • Una richiesta HTTP POST viene inviata alla route api/todoitems .
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));
}

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene richiamata la funzione getItems per aggiornare la tabella HTML. Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiorna un'attività

L'aggiornamento di un elemento attività è simile all'aggiunta di un elemento. Esistono tuttavia due differenze significative:

  • Alla route viene aggiunto come suffisso l'identificatore univoco dell'elemento da aggiornare. Ad esempio, api/todoitems/1.
  • Il verbo di azione HTTP è PUT, come indicato dall'opzione 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));

Elimina un'attività

Per eliminare un'attività, impostare l'opzione method della richiesta su DELETE e specificare l'identificatore univoco dell'attività nell'URL.

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

Vai al tutorial successivo per scoprire come generare pagine della guida dell'API Web:

Questa esercitazione illustra come chiamare un'API Web ASP.NET Core con JavaScript usando l'API Fetch.

Prerequisiti

Chiamare l'API Web con JavaScript

In questa sezione aggiungerai una pagina HTML contenente i form per creare e gestire le attività da svolgere. Agli elementi della pagina vengono associati gestori eventi. I gestori eventi generano richieste HTTP ai metodi di azione dell'API Web. La funzione fetch dell'API Fetch avvia ogni richiesta HTTP.

La funzione fetch restituisce un oggetto Promise che contiene una risposta HTTP rappresentata come oggetto Response. Un modello comune consiste nell'estrarre il corpo della risposta JSON richiamando la funzione json per l'oggetto Response. JavaScript aggiorna la pagina con i dettagli della risposta dell'API Web.

La chiamata fetch più semplice accetta un solo parametro che rappresenta la route. Un secondo parametro, noto come oggetto init, è facoltativo. init viene usato per configurare la richiesta HTTP.

  1. Configurare l'app in modo che gestisca i file statici e consenta il mapping di file predefinito. Il codice evidenziato seguente è necessario nel Configure metodo di 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. Creare una cartella wwwroot nella radice del progetto.

  3. Creare una cartella css all'interno della cartella wwwroot .

  4. Creare una cartella js all'interno della cartella wwwroot .

  5. Aggiungere un file HTML denominato index.html alla cartella wwwroot . Sostituire il contenuto di index.html con il markup seguente:

    <!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. Aggiungere un file CSS denominato site.css alla cartella wwwroot/css . Sostituire il contenuto di site.css con gli stili seguenti:

    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. Aggiungere un file JavaScript denominato site.js alla cartella wwwroot/js . Sostituire il contenuto di site.js con il codice seguente:

    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;
    }
    

Può essere necessario modificare le impostazioni di avvio del progetto ASP.NET Core per il test della pagina HTML in locale:

  1. Aprire Properties\launchSettings.json.
  2. Rimuovere la proprietà launchUrl per fare in modo che l'app si apra in index.html, ovvero nel file predefinito del progetto.

In questo esempio vengono chiamati tutti i metodi CRUD dell'API Web. Di seguito sono disponibili spiegazioni per le richieste dell'API Web.

Ottieni un elenco di cose da fare

Nel codice seguente viene inviata una richiesta HTTP GET alla route api/todoitems :

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

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene chiamata la funzione _displayItems. Ogni elemento attività nel parametro matrice accettato da _displayItems viene aggiunto a una tabella con i pulsanti Edit (Modifica) e Delete (Elimina). Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiungere un'attività

Nel codice seguente:

  • Viene dichiarata una variabile item per costruire una rappresentazione letterale di un oggetto dell'elemento da fare.
  • Una richiesta di recupero viene configurata con le opzioni seguenti:
    • method: specifica il verbo di azione HTTP POST.
    • body: specifica la rappresentazione JSON del corpo della richiesta. Il codice JSON viene prodotto passando il valore letterale dell'oggetto archiviato in item alla funzione JSON.stringify.
    • headers: specifica le intestazioni Accept e Content-Type della richiesta HTTP. Entrambe le intestazioni sono impostate su application/json per specificare rispettivamente il tipo di contenuto ricevuto e quello inviato.
  • Una richiesta HTTP POST viene inviata alla route api/todoitems .
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));
}

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene richiamata la funzione getItems per aggiornare la tabella HTML. Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiorna un'attività

L'aggiornamento di un elemento attività è simile all'aggiunta di un elemento. Esistono tuttavia due differenze significative:

  • Alla route viene aggiunto come suffisso l'identificatore univoco dell'elemento da aggiornare. Ad esempio, api/todoitems/1.
  • Il verbo di azione HTTP è PUT, come indicato dall'opzione 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));

Elimina un'attività

Per eliminare un'attività, impostare l'opzione method della richiesta su DELETE e specificare l'identificatore univoco dell'attività nell'URL.

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

Vai al tutorial successivo per scoprire come generare pagine della guida dell'API Web:

Questa esercitazione illustra come chiamare un'API Web ASP.NET Core con JavaScript usando l'API Fetch.

Prerequisiti

Chiamare l'API Web con JavaScript

In questa sezione, aggiungerai una pagina HTML contenente i moduli per creare e gestire le attività. Agli elementi della pagina vengono associati gestori eventi. I gestori eventi generano richieste HTTP ai metodi di azione dell'API Web. La funzione fetch dell'API Fetch avvia ogni richiesta HTTP.

La funzione fetch restituisce un oggetto Promise che contiene una risposta HTTP rappresentata come oggetto Response. Un modello comune consiste nell'estrarre il corpo della risposta JSON richiamando la funzione json per l'oggetto Response. JavaScript aggiorna la pagina con i dettagli della risposta dell'API Web.

La chiamata fetch più semplice accetta un solo parametro che rappresenta la route. Un secondo parametro, noto come oggetto init, è facoltativo. init viene usato per configurare la richiesta HTTP.

  1. Configurare l'app in modo che gestisca i file statici e consenta il mapping di file predefinito. Il codice evidenziato seguente è necessario 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. Creare una cartella wwwroot nella radice del progetto.

  2. Creare una cartella css all'interno della cartella wwwroot .

  3. Creare una cartella js all'interno della cartella wwwroot .

  4. Aggiungere un file HTML denominato index.html alla cartella wwwroot . Sostituire il contenuto di index.html con il markup seguente:

    <!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. Aggiungere un file CSS denominato site.css alla cartella wwwroot/css . Sostituire il contenuto di site.css con gli stili seguenti:

    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. Aggiungere un file JavaScript denominato site.js alla cartella wwwroot/js . Sostituire il contenuto di site.js con il codice seguente:

    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;
    }
    

Può essere necessario modificare le impostazioni di avvio del progetto ASP.NET Core per il test della pagina HTML in locale:

  1. Aprire Properties\launchSettings.json.
  2. Rimuovere la proprietà launchUrl per fare in modo che l'app si apra su index.html—il file predefinito del progetto.

In questo esempio vengono chiamati tutti i metodi CRUD dell'API Web. Di seguito sono disponibili spiegazioni per le richieste dell'API Web.

Ottieni un elenco di attività da svolgere

Nel codice seguente viene inviata una richiesta HTTP GET alla route api/todoitems :

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

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene chiamata la funzione _displayItems. Ogni elemento dell'elenco delle attività nel parametro array accettato da _displayItems viene aggiunto a una tabella con i pulsanti Edit e Delete. Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiungi un'attività da fare

Nel codice seguente:

  • Viene dichiarata una variabile item per costruire una rappresentazione letterale di un oggetto dell'elemento da fare.
  • Una richiesta di recupero viene configurata con le opzioni seguenti:
    • method: specifica il verbo di azione HTTP POST.
    • body: specifica la rappresentazione JSON del corpo della richiesta. Il codice JSON viene prodotto passando il valore letterale dell'oggetto archiviato in item alla funzione JSON.stringify.
    • headers: specifica le intestazioni Accept e Content-Type della richiesta HTTP. Entrambe le intestazioni sono impostate su application/json per specificare rispettivamente il tipo di contenuto ricevuto e quello inviato.
  • Una richiesta HTTP POST viene inviata alla route api/todoitems .
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));
}

Quando l'API Web restituisce un codice di stato di esecuzione riuscita, viene richiamata la funzione getItems per aggiornare la tabella HTML. Se la richiesta dell'API Web ha esito negativo, viene registrato un errore nella console del browser.

Aggiorna un'attività

L'aggiornamento di un elemento attività è simile all'aggiunta di un elemento. Esistono tuttavia due differenze significative:

  • Alla route viene aggiunto come suffisso l'identificatore univoco dell'elemento da aggiornare. Ad esempio, api/todoitems/1.
  • Il verbo di azione HTTP è PUT, come indicato dall'opzione 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));

Elimina un'attività

Per eliminare un'attività, impostare l'opzione method della richiesta su DELETE e specificare l'identificatore univoco dell'attività nell'URL.

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

Vai al tutorial successivo per scoprire come generare pagine della guida dell'API Web: