Självstudie: Anropa ett ASP.NET Core webb-API med JavaScript

Av Rick Anderson

Den här självstudien visar hur du anropar ett ASP.NET Core webb-API med JavaScript med hjälp av Fetch API.

Förutsättningar

Anropa webb-API:et med JavaScript

I det här avsnittet lägger du till en HTML-sida som innehåller formulär för att skapa och hantera to-do objekt. Händelsehanterare är kopplade till element på sidan. Händelsehanterarna resulterar i HTTP-begäranden till webb-API:ets åtgärdsmetoder. Funktionen Fetch API fetch initierar varje HTTP-begäran.

Funktionen fetch returnerar ett Promise objekt som innehåller ett HTTP-svar som representeras som ett Response objekt. Ett vanligt mönster är att extrahera JSON-svarstexten json genom att anropa funktionen på Response objektet. JavaScript uppdaterar sidan med information från webb-API:ets svar.

Det enklaste fetch anropet accepterar en enda parameter som representerar vägen. En andra parameter, som kallas objektet init , är valfri. init används för att konfigurera HTTP-begäran.

  1. Konfigurera appen för att betjäna statiska filer och aktivera standardfilsmappning. Följande markerade kod behövs i 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. Skapa en wwwroot-mapp i projektroten.

  2. Skapa en css-mapp i mappen wwwroot .

  3. Skapa en js-mapp i mappen wwwroot .

  4. Lägg till en HTML-fil med namnet index.html i mappen wwwroot . Ersätt innehållet i index.html med följande markering:

    <!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. Lägg till en CSS-fil med namnet site.css i mappen wwwroot/css . Ersätt innehållet i site.css med följande format:

    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. Lägg till en JavaScript-fil med namnet site.js i mappen wwwroot/js . Ersätt innehållet i site.js med följande kod:

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

En ändring av ASP.NET Core projektets startinställningar kan krävas för att testa HTML-sidan lokalt:

  1. Öppna Properties\launchSettings.json.
  2. launchUrl Ta bort egenskapen för att tvinga appen att öppnas på index.html– projektets standardfil.

I det här exemplet anropas alla CRUD-metoder i webb-API:et. Följande är förklaringar av webb-API-begäranden.

Hämta en lista över to-do objekt

I följande kod skickas en HTTP GET-begäran till api/todoitems-vägen :

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

När webb-API:et returnerar en lyckad statuskod _displayItems anropas funktionen. Varje to-do objekt i matrisparametern som accepteras av _displayItems läggs till i en tabell med knapparna Redigera och Ta bort . Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Lägga till ett to-do objekt

I följande kod:

  • En item variabel deklareras för att konstruera en objektliteral representation av det to-do objektet.
  • En hämtningsbegäran konfigureras med följande alternativ:
    • method– anger HTTP-åtgärdsverbet POST.
    • body– anger JSON-representationen av begärandetexten. JSON skapas genom att objektliteralen som lagras i item skickas till funktionen JSON.stringify .
    • headers – anger HTTP-begärandehuvudena Accept och Content-Type. Båda rubrikerna är inställda application/json på för att ange medietypen som tas emot respektive skickas.
  • En HTTP POST-begäran skickas till api/todoitems-vägen .
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));
}

När webb-API:et returnerar en lyckad statuskod getItems anropas funktionen för att uppdatera HTML-tabellen. Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Uppdatera ett to-do objekt

Att uppdatera ett to-do objekt liknar att lägga till ett objekt. Det finns dock två betydande skillnader:

  • Sökvägen har den unika identifieraren för objektet som ska uppdateras som suffix. Till exempel api/todoitems/1.
  • HTTP-åtgärdsverb är PUT, vilket anges av alternativet 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));

Ta bort ett to-do objekt

Om du vill ta bort ett to-do objekt anger du alternativet för begäran method till DELETE och anger objektets unika identifierare i URL:en.

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

Gå till nästa självstudiekurs för att lära dig hur du genererar hjälpsidor för webb-API:er:

Den här självstudien visar hur du anropar ett ASP.NET Core webb-API med JavaScript med hjälp av Fetch API.

Förutsättningar

Anropa webb-API:et med JavaScript

I det här avsnittet lägger du till en HTML-sida som innehåller formulär för att skapa och hantera to-do objekt. Händelsehanterare är kopplade till element på sidan. Händelsehanterarna resulterar i HTTP-begäranden till webb-API:ets åtgärdsmetoder. Funktionen Fetch API fetch initierar varje HTTP-begäran.

Funktionen fetch returnerar ett Promise objekt som innehåller ett HTTP-svar som representeras som ett Response objekt. Ett vanligt mönster är att extrahera JSON-svarstexten json genom att anropa funktionen på Response objektet. JavaScript uppdaterar sidan med information från webb-API:ets svar.

Det enklaste fetch anropet accepterar en enda parameter som representerar vägen. En andra parameter, som kallas objektet init , är valfri. init används för att konfigurera HTTP-begäran.

  1. Konfigurera appen för att betjäna statiska filer och aktivera standardfilsmappning. Följande markerade kod behövs i Configure metoden 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. Skapa en wwwroot-mapp i projektroten.

  3. Skapa en css-mapp i mappen wwwroot .

  4. Skapa en js-mapp i mappen wwwroot .

  5. Lägg till en HTML-fil med namnet index.html i mappen wwwroot . Ersätt innehållet i index.html med följande markering:

    <!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. Lägg till en CSS-fil med namnet site.css i mappen wwwroot/css . Ersätt innehållet i site.css med följande format:

    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. Lägg till en JavaScript-fil med namnet site.js i mappen wwwroot/js . Ersätt innehållet i site.js med följande kod:

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

En ändring av ASP.NET Core projektets startinställningar kan krävas för att testa HTML-sidan lokalt:

  1. Öppna Properties\launchSettings.json.
  2. launchUrl Ta bort egenskapen för att tvinga appen att öppnas på index.html– projektets standardfil.

I det här exemplet anropas alla CRUD-metoder i webb-API:et. Följande är förklaringar av webb-API-begäranden.

Hämta en lista över to-do objekt

I följande kod skickas en HTTP GET-begäran till api/todoitems-vägen :

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

När webb-API:et returnerar en lyckad statuskod _displayItems anropas funktionen. Varje to-do objekt i matrisparametern som accepteras av _displayItems läggs till i en tabell med knapparna Redigera och Ta bort . Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Lägga till ett to-do objekt

I följande kod:

  • En item variabel deklareras för att konstruera en objektliteral representation av det to-do objektet.
  • En hämtningsbegäran konfigureras med följande alternativ:
    • method– anger HTTP-åtgärdsverbet POST.
    • body– anger JSON-representationen av begärandetexten. JSON skapas genom att objektliteralen som lagras i item skickas till funktionen JSON.stringify .
    • headers – anger HTTP-begärandehuvudena Accept och Content-Type. Båda rubrikerna är inställda application/json på för att ange medietypen som tas emot respektive skickas.
  • En HTTP POST-begäran skickas till api/todoitems-vägen .
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));
}

När webb-API:et returnerar en lyckad statuskod getItems anropas funktionen för att uppdatera HTML-tabellen. Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Uppdatera ett to-do objekt

Att uppdatera ett to-do objekt liknar att lägga till ett objekt. Det finns dock två betydande skillnader:

  • Sökvägen har den unika identifieraren för objektet som ska uppdateras som suffix. Till exempel api/todoitems/1.
  • HTTP-åtgärdsverb är PUT, vilket anges av alternativet 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));

Ta bort ett to-do objekt

Om du vill ta bort ett to-do objekt anger du alternativet för begäran method till DELETE och anger objektets unika identifierare i URL:en.

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

Gå till nästa självstudiekurs för att lära dig hur du genererar hjälpsidor för webb-API:er:

Den här självstudien visar hur du anropar ett ASP.NET Core webb-API med JavaScript med hjälp av Fetch API.

Förutsättningar

Anropa webb-API:et med JavaScript

I det här avsnittet lägger du till en HTML-sida som innehåller formulär för att skapa och hantera to-do objekt. Händelsehanterare är kopplade till element på sidan. Händelsehanterarna resulterar i HTTP-begäranden till webb-API:ets åtgärdsmetoder. Funktionen Fetch API fetch initierar varje HTTP-begäran.

Funktionen fetch returnerar ett Promise objekt som innehåller ett HTTP-svar som representeras som ett Response objekt. Ett vanligt mönster är att extrahera JSON-svarstexten json genom att anropa funktionen på Response objektet. JavaScript uppdaterar sidan med information från webb-API:ets svar.

Det enklaste fetch anropet accepterar en enda parameter som representerar vägen. En andra parameter, som kallas objektet init , är valfri. init används för att konfigurera HTTP-begäran.

  1. Konfigurera appen för att betjäna statiska filer och aktivera standardfilsmappning. Följande markerade kod behövs i 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. Skapa en wwwroot-mapp i projektroten.

  2. Skapa en css-mapp i mappen wwwroot .

  3. Skapa en js-mapp i mappen wwwroot .

  4. Lägg till en HTML-fil med namnet index.html i mappen wwwroot . Ersätt innehållet i index.html med följande markering:

    <!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. Lägg till en CSS-fil med namnet site.css i mappen wwwroot/css . Ersätt innehållet i site.css med följande format:

    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. Lägg till en JavaScript-fil med namnet site.js i mappen wwwroot/js . Ersätt innehållet i site.js med följande kod:

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

En ändring av ASP.NET Core projektets startinställningar kan krävas för att testa HTML-sidan lokalt:

  1. Öppna Properties\launchSettings.json.
  2. launchUrl Ta bort egenskapen för att tvinga appen att öppnas på index.html– projektets standardfil.

I det här exemplet anropas alla CRUD-metoder i webb-API:et. Följande är förklaringar av webb-API-begäranden.

Hämta en lista över to-do objekt

I följande kod skickas en HTTP GET-begäran till api/todoitems-vägen :

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

När webb-API:et returnerar en lyckad statuskod _displayItems anropas funktionen. Varje to-do objekt i matrisparametern som accepteras av _displayItems läggs till i en tabell med knapparna Redigera och Ta bort . Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Lägga till ett to-do objekt

I följande kod:

  • En item variabel deklareras för att konstruera en objektliteral representation av det to-do objektet.
  • En hämtningsbegäran konfigureras med följande alternativ:
    • method– anger HTTP-åtgärdsverbet POST.
    • body– anger JSON-representationen av begärandetexten. JSON skapas genom att objektliteralen som lagras i item skickas till funktionen JSON.stringify .
    • headers – anger HTTP-begärandehuvudena Accept och Content-Type. Båda rubrikerna är inställda application/json på för att ange medietypen som tas emot respektive skickas.
  • En HTTP POST-begäran skickas till api/todoitems-vägen .
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));
}

När webb-API:et returnerar en lyckad statuskod getItems anropas funktionen för att uppdatera HTML-tabellen. Om webb-API-begäran misslyckas loggas ett fel i webbläsarens konsol.

Uppdatera ett to-do objekt

Att uppdatera ett to-do objekt liknar att lägga till ett objekt. Det finns dock två betydande skillnader:

  • Sökvägen har den unika identifieraren för objektet som ska uppdateras som suffix. Till exempel api/todoitems/1.
  • HTTP-åtgärdsverb är PUT, vilket anges av alternativet 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));

Ta bort ett to-do objekt

Om du vill ta bort ett to-do objekt anger du alternativet för begäran method till DELETE och anger objektets unika identifierare i URL:en.

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

Gå till nästa självstudiekurs för att lära dig hur du genererar hjälpsidor för webb-API:er: