Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core za pomocą języka JavaScript

Autor: Rick Anderson

W tym samouczku pokazano, jak wywołać internetowy interfejs API platformy ASP.NET Core za pomocą języka JavaScript przy użyciu interfejsu API pobierania.

Wymagania wstępne

Wywoływanie internetowego interfejsu API za pomocą języka JavaScript

W tej sekcji dodasz stronę HTML zawierającą formularze do tworzenia elementów zadań do wykonania i zarządzania nimi. Programy obsługi zdarzeń są dołączane do elementów na stronie. Programy obsługi zdarzeń powodują żądania HTTP do metod akcji internetowego interfejsu API. Funkcja interfejsu API pobierania fetch inicjuje każde żądanie HTTP.

Funkcja fetch zwraca Promise obiekt, który zawiera odpowiedź HTTP reprezentowaną Response jako obiekt. Typowym wzorcem jest wyodrębnienie JStreści odpowiedzi ON przez wywołanie json funkcji w Response obiekcie. Język JavaScript aktualizuje stronę ze szczegółami odpowiedzi internetowego interfejsu API.

Najprostsze fetch wywołanie akceptuje pojedynczy parametr reprezentujący trasę. Drugi parametr, znany jako init obiekt, jest opcjonalny. init służy do konfigurowania żądania HTTP.

  1. Skonfiguruj aplikację do obsługi plików statycznych i włącz domyślne mapowanie plików. W pliku jest wymagany następujący wyróżniony kod: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. Utwórz folder wwwroot w katalogu głównym projektu.

  2. Utwórz folder css w folderze wwwroot.

  3. Utwórz folder js w folderze wwwroot.

  4. Dodaj plik HTML o nazwie index.html do folderu wwwroot . Zastąp zawartość index.html następującym znacznikiem:

    <!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. Dodaj plik CSS o nazwie site.css do folderu wwwroot/css . Zastąp zawartość site.css następującymi stylami:

    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. Dodaj plik JavaScript o nazwie site.js do folderu wwwroot/js . Zastąp zawartość site.js następującym kodem:

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

Aby lokalnie przetestować stronę HTML, może być wymagana zmiana ustawień uruchamiania projektu ASP.NET Core:

  1. Otwórz plik Properties\launch Ustawienia.json.
  2. Usuń właściwość, launchUrl aby wymusić otwarcie aplikacji pod index.htmladresem — domyślny plik projektu.

Ten przykład wywołuje wszystkie metody CRUD internetowego interfejsu API. Poniżej przedstawiono wyjaśnienia dotyczące żądań internetowego interfejsu API.

Pobieranie listy elementów do wykonania

W poniższym kodzie żądanie HTTP GET jest wysyłane do trasy interfejsu API/todoitems :

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

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, wywoływana _displayItems jest funkcja. Każdy element do wykonania w parametrze tablicy akceptowanym przez _displayItems element jest dodawany do tabeli za pomocą przycisków Edytuj i Usuń . Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Dodawanie elementu do wykonania

W poniższym kodzie:

  • Zmienna item jest zadeklarowana w celu skonstruowania reprezentacji literału obiektu elementu do wykonania.
  • Żądanie pobierania jest konfigurowane przy użyciu następujących opcji:
    • method— określa czasownik akcji HTTP POST.
    • body— określa reprezentację JSON treści żądania. Funkcja JSON jest generowany przez przekazanie literału obiektu przechowywanego JSw item funkcji ON.stringify.
    • headers— określa Accept nagłówki żądań HTTP i Content-Type . Oba nagłówki są ustawione na application/json wartość , aby określić typ nośnika odbieranego i wysyłanego odpowiednio.
  • Żądanie HTTP POST jest wysyłane do trasy 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));
}

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, getItems funkcja jest wywoływana w celu zaktualizowania tabeli HTML. Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Aktualizowanie elementu do wykonania

Aktualizowanie elementu do wykonania jest podobne do dodawania elementu; istnieją jednak dwie istotne różnice:

  • Trasa jest sufiksowana unikatowym identyfikatorem elementu do zaktualizowania. Na przykład api/todoitems/1.
  • Czasownik akcji HTTP to PUT, zgodnie z opcją 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));

Usuwanie elementu do wykonania

Aby usunąć element do wykonania, ustaw opcję żądania method na DELETE i określ unikatowy identyfikator elementu w adresie URL.

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

Przejdź do następnego samouczka, aby dowiedzieć się, jak generować strony pomocy internetowego interfejsu API:

W tym samouczku pokazano, jak wywołać internetowy interfejs API platformy ASP.NET Core za pomocą języka JavaScript przy użyciu interfejsu API pobierania.

Wymagania wstępne

Wywoływanie internetowego interfejsu API za pomocą języka JavaScript

W tej sekcji dodasz stronę HTML zawierającą formularze do tworzenia elementów zadań do wykonania i zarządzania nimi. Programy obsługi zdarzeń są dołączane do elementów na stronie. Programy obsługi zdarzeń powodują żądania HTTP do metod akcji internetowego interfejsu API. Funkcja interfejsu API pobierania fetch inicjuje każde żądanie HTTP.

Funkcja fetch zwraca Promise obiekt, który zawiera odpowiedź HTTP reprezentowaną Response jako obiekt. Typowym wzorcem jest wyodrębnienie JStreści odpowiedzi ON przez wywołanie json funkcji w Response obiekcie. Język JavaScript aktualizuje stronę ze szczegółami odpowiedzi internetowego interfejsu API.

Najprostsze fetch wywołanie akceptuje pojedynczy parametr reprezentujący trasę. Drugi parametr, znany jako init obiekt, jest opcjonalny. init służy do konfigurowania żądania HTTP.

  1. Skonfiguruj aplikację do obsługi plików statycznych i włącz domyślne mapowanie plików. Poniższy wyróżniony kod jest wymagany w Configure metodzie :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. Utwórz folder wwwroot w katalogu głównym projektu.

  3. Utwórz folder css w folderze wwwroot.

  4. Utwórz folder js w folderze wwwroot.

  5. Dodaj plik HTML o nazwie index.html do folderu wwwroot . Zastąp zawartość index.html następującym znacznikiem:

    <!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. Dodaj plik CSS o nazwie site.css do folderu wwwroot/css . Zastąp zawartość site.css następującymi stylami:

    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. Dodaj plik JavaScript o nazwie site.js do folderu wwwroot/js . Zastąp zawartość site.js następującym kodem:

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

Aby lokalnie przetestować stronę HTML, może być wymagana zmiana ustawień uruchamiania projektu ASP.NET Core:

  1. Otwórz plik Properties\launch Ustawienia.json.
  2. Usuń właściwość, launchUrl aby wymusić otwarcie aplikacji pod index.htmladresem — domyślny plik projektu.

Ten przykład wywołuje wszystkie metody CRUD internetowego interfejsu API. Poniżej przedstawiono wyjaśnienia dotyczące żądań internetowego interfejsu API.

Pobieranie listy elementów do wykonania

W poniższym kodzie żądanie HTTP GET jest wysyłane do trasy interfejsu API/todoitems :

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

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, wywoływana _displayItems jest funkcja. Każdy element do wykonania w parametrze tablicy akceptowanym przez _displayItems element jest dodawany do tabeli za pomocą przycisków Edytuj i Usuń . Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Dodawanie elementu do wykonania

W poniższym kodzie:

  • Zmienna item jest zadeklarowana w celu skonstruowania reprezentacji literału obiektu elementu do wykonania.
  • Żądanie pobierania jest konfigurowane przy użyciu następujących opcji:
    • method— określa czasownik akcji HTTP POST.
    • body— określa reprezentację JSON treści żądania. Funkcja JSON jest generowany przez przekazanie literału obiektu przechowywanego JSw item funkcji ON.stringify.
    • headers— określa Accept nagłówki żądań HTTP i Content-Type . Oba nagłówki są ustawione na application/json wartość , aby określić typ nośnika odbieranego i wysyłanego odpowiednio.
  • Żądanie HTTP POST jest wysyłane do trasy 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));
}

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, getItems funkcja jest wywoływana w celu zaktualizowania tabeli HTML. Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Aktualizowanie elementu do wykonania

Aktualizowanie elementu do wykonania jest podobne do dodawania elementu; istnieją jednak dwie istotne różnice:

  • Trasa jest sufiksowana unikatowym identyfikatorem elementu do zaktualizowania. Na przykład api/todoitems/1.
  • Czasownik akcji HTTP to PUT, zgodnie z opcją 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));

Usuwanie elementu do wykonania

Aby usunąć element do wykonania, ustaw opcję żądania method na DELETE i określ unikatowy identyfikator elementu w adresie URL.

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

Przejdź do następnego samouczka, aby dowiedzieć się, jak generować strony pomocy internetowego interfejsu API:

W tym samouczku pokazano, jak wywołać internetowy interfejs API platformy ASP.NET Core za pomocą języka JavaScript przy użyciu interfejsu API pobierania.

Wymagania wstępne

Wywoływanie internetowego interfejsu API za pomocą języka JavaScript

W tej sekcji dodasz stronę HTML zawierającą formularze do tworzenia elementów zadań do wykonania i zarządzania nimi. Programy obsługi zdarzeń są dołączane do elementów na stronie. Programy obsługi zdarzeń powodują żądania HTTP do metod akcji internetowego interfejsu API. Funkcja interfejsu API pobierania fetch inicjuje każde żądanie HTTP.

Funkcja fetch zwraca Promise obiekt, który zawiera odpowiedź HTTP reprezentowaną Response jako obiekt. Typowym wzorcem jest wyodrębnienie JStreści odpowiedzi ON przez wywołanie json funkcji w Response obiekcie. Język JavaScript aktualizuje stronę ze szczegółami odpowiedzi internetowego interfejsu API.

Najprostsze fetch wywołanie akceptuje pojedynczy parametr reprezentujący trasę. Drugi parametr, znany jako init obiekt, jest opcjonalny. init służy do konfigurowania żądania HTTP.

  1. Skonfiguruj aplikację do obsługi plików statycznych i włącz domyślne mapowanie plików. W pliku jest wymagany następujący wyróżniony kod: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. Utwórz folder wwwroot w katalogu głównym projektu.

  2. Utwórz folder css w folderze wwwroot.

  3. Utwórz folder js w folderze wwwroot.

  4. Dodaj plik HTML o nazwie index.html do folderu wwwroot . Zastąp zawartość index.html następującym znacznikiem:

    <!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. Dodaj plik CSS o nazwie site.css do folderu wwwroot/css . Zastąp zawartość site.css następującymi stylami:

    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. Dodaj plik JavaScript o nazwie site.js do folderu wwwroot/js . Zastąp zawartość site.js następującym kodem:

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

Aby lokalnie przetestować stronę HTML, może być wymagana zmiana ustawień uruchamiania projektu ASP.NET Core:

  1. Otwórz plik Properties\launch Ustawienia.json.
  2. Usuń właściwość, launchUrl aby wymusić otwarcie aplikacji pod index.htmladresem — domyślny plik projektu.

Ten przykład wywołuje wszystkie metody CRUD internetowego interfejsu API. Poniżej przedstawiono wyjaśnienia dotyczące żądań internetowego interfejsu API.

Pobieranie listy elementów do wykonania

W poniższym kodzie żądanie HTTP GET jest wysyłane do trasy interfejsu API/todoitems :

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

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, wywoływana _displayItems jest funkcja. Każdy element do wykonania w parametrze tablicy akceptowanym przez _displayItems element jest dodawany do tabeli za pomocą przycisków Edytuj i Usuń . Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Dodawanie elementu do wykonania

W poniższym kodzie:

  • Zmienna item jest zadeklarowana w celu skonstruowania reprezentacji literału obiektu elementu do wykonania.
  • Żądanie pobierania jest konfigurowane przy użyciu następujących opcji:
    • method— określa czasownik akcji HTTP POST.
    • body— określa reprezentację JSON treści żądania. Funkcja JSON jest generowany przez przekazanie literału obiektu przechowywanego JSw item funkcji ON.stringify.
    • headers— określa Accept nagłówki żądań HTTP i Content-Type . Oba nagłówki są ustawione na application/json wartość , aby określić typ nośnika odbieranego i wysyłanego odpowiednio.
  • Żądanie HTTP POST jest wysyłane do trasy 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));
}

Gdy internetowy interfejs API zwraca kod stanu zakończony powodzeniem, getItems funkcja jest wywoływana w celu zaktualizowania tabeli HTML. Jeśli żądanie internetowego interfejsu API zakończy się niepowodzeniem, w konsoli przeglądarki zostanie zarejestrowany błąd.

Aktualizowanie elementu do wykonania

Aktualizowanie elementu do wykonania jest podobne do dodawania elementu; istnieją jednak dwie istotne różnice:

  • Trasa jest sufiksowana unikatowym identyfikatorem elementu do zaktualizowania. Na przykład api/todoitems/1.
  • Czasownik akcji HTTP to PUT, zgodnie z opcją 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));

Usuwanie elementu do wykonania

Aby usunąć element do wykonania, ustaw opcję żądania method na DELETE i określ unikatowy identyfikator elementu w adresie URL.

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

Przejdź do następnego samouczka, aby dowiedzieć się, jak generować strony pomocy internetowego interfejsu API: