Samouczek: tworzenie internetowego interfejsu API przy użyciu platformy ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autorzy: Rick Anderson i Kirk Larkin

W tym samouczku przedstawiono podstawy tworzenia internetowego interfejsu API opartego na kontrolerze, który używa bazy danych. Innym podejściem do tworzenia interfejsów API w środowisku ASP.NET Core jest utworzenie minimalnych interfejsów API. Aby uzyskać pomoc dotyczącą wybierania między minimalnymi interfejsami API i interfejsami API opartymi na kontrolerach, zobacz Omówienie interfejsów API. Aby zapoznać się z samouczkiem dotyczącym tworzenia minimalnego interfejsu API, zobacz Samouczek: tworzenie minimalnego interfejsu API przy użyciu platformy ASP.NET Core.

Omówienie

Ten samouczek tworzy następujący interfejs API:

Interfejs API opis Treść żądania Treść odpowiedzi
GET /api/todoitems Pobieranie wszystkich elementów do wykonania Brak Tablica elementów do wykonania
GET /api/todoitems/{id} Pobieranie elementu według identyfikatora Brak Element do wykonania
POST /api/todoitems Dodawanie nowego elementu Element do wykonania Element do wykonania
PUT /api/todoitems/{id} Aktualizowanie istniejącego elementu Element do wykonania Brak
DELETE /api/todoitems/{id}     Usuwanie elementu Brak Brak

Na poniższym diagramie przedstawiono projekt aplikacji.

Klient jest reprezentowany przez pole po lewej stronie. Przesyła żądanie i odbiera odpowiedź z aplikacji, pole narysowane po prawej stronie. W polu aplikacji trzy pola reprezentują kontroler, model i warstwę dostępu do danych. Żądanie jest wprowadzane do kontrolera aplikacji, a operacje odczytu/zapisu są wykonywane między kontrolerem a warstwą dostępu do danych. Model jest serializowany i zwracany do klienta w odpowiedzi.

Wymagania wstępne

Tworzenie projektu internetowego

  • W menu Plik wybierz pozycję Nowy>projekt.
  • Wprowadź internetowy interfejs API w polu wyszukiwania.
  • Wybierz szablon internetowego interfejsu API platformy ASP.NET Core i wybierz pozycję Dalej.
  • W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę TodoApi i wybierz pozycję Dalej.
  • W oknie dialogowym Dodatkowe informacje:
    • Upewnij się, że platforma .NET 8.0 (obsługa długoterminowa).
    • Upewnij się, że pole wyboru Użyj kontrolerów (usuń zaznaczenie pola wyboru, aby używać minimalnych interfejsów API) jest zaznaczone.
    • Upewnij się, że zaznaczono pole wyboru Włącz obsługę interfejsu OpenAPI.
    • Wybierz pozycję Utwórz.

Dodawanie pakietu NuGet

Aby obsługiwać bazę danych używaną w tym samouczku, należy dodać pakiet NuGet.

  • W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > Zarządzaj pakietami NuGet dla rozwiązania.
  • Wybierz kartę Przeglądaj.
  • Wprowadź ciąg Microsoft.EntityFrameworkCore.InMemory w polu wyszukiwania, a następnie wybierz pozycję Microsoft.EntityFrameworkCore.InMemory.
  • Zaznacz pole wyboru Projekt w okienku po prawej stronie, a następnie wybierz pozycję Zainstaluj.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Testowanie projektu

Szablon projektu tworzy interfejs API z obsługą WeatherForecast struktury Swagger.

Naciśnij klawisze Ctrl+F5, aby uruchomić bez debugera.

Program Visual Studio wyświetla następujące okno dialogowe, gdy projekt nie jest jeszcze skonfigurowany do używania protokołu SSL:

Ten projekt jest skonfigurowany do używania protokołu SSL. Aby uniknąć ostrzeżeń SSL w przeglądarce, możesz zaufać certyfikatowi z podpisem własnym wygenerowanemu przez usługę IIS Express. Czy chcesz ufać certyfikatowi SSL usług IIS Express?

Wybierz pozycję Tak , jeśli ufasz certyfikatowi SSL usług IIS Express.

Zostanie wyświetlone następujące okno dialogowe:

Okno dialogowe ostrzeżenia o zabezpieczeniach

Wybierz pozycję Tak, jeśli wyrażasz zgodę na zaufanie certyfikatowi programistycznemu.

Aby uzyskać informacje na temat zaufania przeglądarce Firefox, zobacz Błąd certyfikatu przeglądarki Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.

Program Visual Studio uruchamia domyślną przeglądarkę i przechodzi do https://localhost:<port>/swagger/index.htmllokalizacji , gdzie <port> jest losowo wybranym numerem portu ustawionym podczas tworzenia projektu.

Zostanie wyświetlona strona /swagger/index.html struktury Swagger. Wybierz pozycję GET Try it out>Execute (Pobierz>, wypróbuj wykonanie). Zostanie wyświetlona strona:

  • Polecenie Curl w celu przetestowania interfejsu API WeatherForecast.
  • Adres URL do przetestowania interfejsu API WeatherForecast.
  • Kod odpowiedzi, treść i nagłówki.
  • Pole listy rozwijanej z typami multimediów oraz przykładową wartością i schematem.

Jeśli strona struktury Swagger nie jest wyświetlana, zobacz ten problem z usługą GitHub.

Narzędzie Swagger służy do generowania przydatnej dokumentacji i stron pomocy dla internetowych interfejsów API. W tym samouczku do testowania aplikacji jest używana struktura Swagger. Aby uzyskać więcej informacji na temat struktury Swagger, zobacz dokumentację internetowego interfejsu API platformy ASP.NET Core za pomocą programu Swagger/OpenAPI.

Skopiuj i wklej adres URL żądania w przeglądarce: https://localhost:<port>/weatherforecast

JSZwracany jest komunikat ON podobny do poniższego przykładu:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Dodawanie klasy modelu

Model to zestaw klas reprezentujących dane, którymi zarządza aplikacja. Model dla tej aplikacji jest klasą TodoItem .

  • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt. Wybierz pozycję Dodaj>nowy folder. Nadaj folderowi Modelsnazwę .
  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoItem i wybierz pozycję Dodaj.
  • Zastąp kod szablonu następującym kodem:
namespace TodoApi.Models;

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Właściwość Id działa jako unikatowy klucz w relacyjnej bazie danych.

Klasy modeli mogą znajdować się w dowolnym miejscu w projekcie, ale Models folder jest używany zgodnie z konwencją.

Dodawanie kontekstu bazy danych

Kontekst bazy danych jest klasą główną, która koordynuje funkcje programu Entity Framework dla modelu danych. Ta klasa jest tworzona przez wyprowadzanie z Microsoft.EntityFrameworkCore.DbContext klasy .

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoContext i kliknij przycisk Dodaj.
  • Wprowadź następujące kod:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models;
    
    public class TodoContext : DbContext
    {
        public TodoContext(DbContextOptions<TodoContext> options)
            : base(options)
        {
        }
    
        public DbSet<TodoItem> TodoItems { get; set; } = null!;
    }
    

Rejestrowanie kontekstu bazy danych

W ASP.NET Core usługi, takie jak kontekst bazy danych, muszą być zarejestrowane w kontenerze wstrzykiwania zależności (DI). Kontener udostępnia usługę kontrolerom.

Zaktualizuj Program.cs za pomocą następującego wyróżnionego kodu:

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Powyższy kod ma następujące działanie:

  • Dodaje using dyrektywy.
  • Dodaje kontekst bazy danych do kontenera DI.
  • Określa, że kontekst bazy danych będzie używać bazy danych w pamięci.

Tworzenie szkieletu kontrolera

  • Kliknij prawym przyciskiem myszy folder Controllers .

  • Wybierz pozycję Dodaj>nowy element szkieletowy.

  • Wybierz pozycję Kontroler interfejsu API z akcjami przy użyciu platformy Entity Framework, a następnie wybierz pozycję Dodaj.

  • W oknie dialogowym Dodawanie kontrolera interfejsu API z akcjami przy użyciu programu Entity Framework :

    • Wybierz pozycję TodoItem (TodoApi.Models) w klasie Model.
    • Wybierz pozycję TodoContext (TodoApi.Models) w klasie Kontekst danych.
    • Wybierz Dodaj.

    Jeśli operacja tworzenia szkieletu nie powiedzie się, wybierz pozycję Dodaj , aby spróbować utworzyć szkielet po raz drugi.

Wygenerowany kod:

Szablony ASP.NET Core dla:

  • Kontrolery z widokami znajdują się [action] w szablonie trasy.
  • Kontrolery interfejsów API nie są uwzględniane [action] w szablonie trasy.

[action] Jeśli token nie znajduje się w szablonie trasy, nazwa akcji (nazwa metody) nie jest uwzględniona w punkcie końcowym. Oznacza to, że skojarzona nazwa metody akcji nie jest używana w pasującej trasie.

Aktualizowanie metody PostTodoItem create

Zaktualizuj instrukcję return w elemecie PostTodoItem , aby użyć operatora nameof :

[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //    return CreatedAtAction("PostTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(PostTodoItem), new { id = todoItem.Id }, todoItem);
}

Powyższy kod jest metodą wskazaną HTTP POST[HttpPost] przez atrybut . Metoda pobiera wartość TodoItem z treści żądania HTTP.

Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

Metoda CreatedAtAction:

  • Zwraca kod stanu HTTP 201, jeśli się powiedzie. HTTP 201 to standardowa odpowiedź dla HTTP POST metody, która tworzy nowy zasób na serwerze.
  • Dodaje nagłówek Location do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonego elementu do wykonania. Aby uzyskać więcej informacji, zobacz 10.2.2 201 Created (Utworzono 10.2.2 201).
  • Odwołuje się do akcji w PostTodoItem celu utworzenia Location identyfikatora URI nagłówka. Słowo kluczowe języka C# nameof służy do unikania kodowania na stałe nazwy akcji w wywołaniu CreatedAtAction .

Test PostTodoItem

  • Naciśnij klawisze Ctrl+F5, aby uruchomić aplikację.

  • W oknie przeglądarki struktury Swagger wybierz pozycję POST /api/TodoItems, a następnie wybierz pozycję Wypróbuj.

  • W oknie Wprowadzanie treści żądania zaktualizuj wartość JSWŁ. Przykład:

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • Wybierz przycisk Wykonaj.

    Swagger POST

Testowanie identyfikatora URI nagłówka lokalizacji

W poprzednim wpisie interfejs użytkownika struktury Swagger wyświetla nagłówek lokalizacji w obszarze Nagłówki odpowiedzi. Na przykład location: https://localhost:7260/api/TodoItems/1. Nagłówek lokalizacji zawiera identyfikator URI utworzonego zasobu.

Aby przetestować nagłówek lokalizacji:

  • W oknie przeglądarki struktury Swagger wybierz pozycję GET /api/TodoItems/{id}, a następnie wybierz pozycję Wypróbuj.

  • Wprowadź 1 w polu wejściowym id , a następnie wybierz pozycję Wykonaj.

    Swagger GET

Badanie metod GET

Zaimplementowano dwa punkty końcowe GET:

  • GET /api/todoitems
  • GET /api/todoitems/{id}

W poprzedniej sekcji przedstawiono przykład /api/todoitems/{id} trasy.

Postępuj zgodnie z instrukcjami POST , aby dodać kolejny element zadania do wykonania, a następnie przetestuj /api/todoitems trasę przy użyciu struktury Swagger.

Ta aplikacja używa bazy danych w pamięci. Jeśli aplikacja zostanie zatrzymana i uruchomiona, powyższe żądanie GET nie zwróci żadnych danych. Jeśli żadne dane nie są zwracane, dane POST do aplikacji.

Routing i ścieżki adresów URL

Atrybut [HttpGet] określa metodę, która odpowiada na HTTP GET żądanie. Ścieżka adresu URL dla każdej metody jest skonstruowana w następujący sposób:

  • Zacznij od ciągu szablonu w atrybucie kontrolera Route :

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Zastąp [controller] ciąg nazwą kontrolera, który zgodnie z konwencją jest nazwą klasy kontrolera minus sufiksem "Kontroler". W tym przykładzie nazwa klasy kontrolera to TodoItemsController, więc nazwa kontrolera to "TodoItems". routing ASP.NET Core jest niewrażliwy na wielkość liter.

  • [HttpGet] Jeśli atrybut ma szablon trasy (na przykład [HttpGet("products")]), dołącz go do ścieżki. Ten przykład nie używa szablonu. Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

W poniższej GetTodoItem metodzie "{id}" jest zmienną zastępczą unikatowego identyfikatora elementu do wykonania. Po GetTodoItem wywołaniu wartość "{id}" w adresie URL jest udostępniana metodzie w parametrze id .

[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Wartości zwracane

Zwracany GetTodoItems typ metod i GetTodoItem to ActionResult<T>. ASP.NET Core automatycznie serializuje obiekt włJS. i zapisuje wartość JSON w treści komunikatu odpowiedzi. Kod odpowiedzi dla tego typu zwracanego to 200 OK, zakładając, że nie ma żadnych nieobsługiwane wyjątki. Nieobsługiwane wyjątki są tłumaczone na błędy 5xx.

ActionResult typy zwracane mogą reprezentować szeroką gamę kodów stanu HTTP. Na przykład GetTodoItem może zwrócić dwie różne wartości stanu:

  • Jeśli żaden element nie pasuje do żądanego identyfikatora, metoda zwraca kod błędu stanuNotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią JSodpowiedzi ON. Zwracanie item wyników w HTTP 200 odpowiedzi.

Metoda PutTodoItem

Przeanalizuj metodę PutTodoItem:

[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem jest podobny do PostTodoItemelementu , z wyjątkiem tego, że używa metody HTTP PUT. Odpowiedź to 204 (brak zawartości). Zgodnie ze specyfikacją PUT PROTOKOŁU HTTP żądanie wymaga od klienta wysłania całej zaktualizowanej jednostki, a nie tylko zmian. Aby obsługiwać aktualizacje częściowe, użyj poprawki HTTP PATCH.

Testowanie metody PutTodoItem

W tym przykładzie użyto bazy danych w pamięci, która musi zostać zainicjowana przy każdym uruchomieniu aplikacji. Przed wykonaniem wywołania PUT musi istnieć element w bazie danych. Wywołaj metodę GET, aby upewnić się, że istnieje element w bazie danych przed wykonaniem wywołania PUT.

Za pomocą interfejsu użytkownika struktury Swagger użyj przycisku PUT, aby zaktualizować TodoItem identyfikator o identyfikatorze = 1 i ustawić jego nazwę na "feed fish". Zwróć uwagę, że odpowiedź to HTTP 204 No Content.

Metoda DeleteTodoItem

Przeanalizuj metodę DeleteTodoItem:

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

Testowanie metody DeleteTodoItem

Użyj interfejsu użytkownika struktury Swagger, aby usunąć identyfikator TodoItem o identyfikatorze = 1. Zwróć uwagę, że odpowiedź to HTTP 204 No Content.

Testowanie za pomocą innych narzędzi

Istnieje wiele innych narzędzi, których można użyć do testowania internetowych interfejsów API, na przykład:

Aby uzyskać więcej informacji, zobacz:

Zapobieganie nadmiernemu delegowaniu

Obecnie przykładowa aplikacja uwidacznia cały TodoItem obiekt. Aplikacje produkcyjne zwykle ograniczają dane wejściowe i zwracane przy użyciu podzestawu modelu. Istnieje wiele powodów, dla których jest to ważne. Podzbiór modelu jest zwykle nazywany obiektem transferu danych (DTO), modelem wejściowym lub modelem widoku. Cel DTO jest używany w tym samouczku.

DTO może służyć do:

  • Zapobiegaj nadmiernemu delegowaniu.
  • Ukryj właściwości, których klienci nie powinni wyświetlać.
  • Pomiń niektóre właściwości, aby zmniejszyć rozmiar ładunku.
  • Spłaszczane wykresy obiektów zawierające zagnieżdżone obiekty. Spłaszczone grafy obiektów mogą być wygodniejsze dla klientów.

Aby zademonstrować podejście DTO, zaktualizuj klasę TodoItem tak, aby zawierała pole wpisu tajnego:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
        public string? Secret { get; set; }
    }
}

Pole wpisu tajnego musi być ukryte w tej aplikacji, ale aplikacja administracyjna może ją uwidocznić.

Sprawdź, czy możesz opublikować i pobrać pole wpisu tajnego.

Tworzenie modelu DTO:

namespace TodoApi.Models;

public class TodoItemDTO
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Zaktualizuj element , aby użyć polecenia TodoItemsControllerTodoItemDTO:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi.Controllers;

[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
{
    private readonly TodoContext _context;

    public TodoItemsController(TodoContext context)
    {
        _context = context;
    }

    // GET: api/TodoItems
    [HttpGet]
    public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
    {
        return await _context.TodoItems
            .Select(x => ItemToDTO(x))
            .ToListAsync();
    }

    // GET: api/TodoItems/5
    // <snippet_GetByID>
    [HttpGet("{id}")]
    public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            return NotFound();
        }

        return ItemToDTO(todoItem);
    }
    // </snippet_GetByID>

    // PUT: api/TodoItems/5
    // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
    // <snippet_Update>
    [HttpPut("{id}")]
    public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
    {
        if (id != todoDTO.Id)
        {
            return BadRequest();
        }

        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null)
        {
            return NotFound();
        }

        todoItem.Name = todoDTO.Name;
        todoItem.IsComplete = todoDTO.IsComplete;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
        {
            return NotFound();
        }

        return NoContent();
    }
    // </snippet_Update>

    // POST: api/TodoItems
    // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
    // <snippet_Create>
    [HttpPost]
    public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
    {
        var todoItem = new TodoItem
        {
            IsComplete = todoDTO.IsComplete,
            Name = todoDTO.Name
        };

        _context.TodoItems.Add(todoItem);
        await _context.SaveChangesAsync();

        return CreatedAtAction(
            nameof(GetTodoItem),
            new { id = todoItem.Id },
            ItemToDTO(todoItem));
    }
    // </snippet_Create>

    // DELETE: api/TodoItems/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null)
        {
            return NotFound();
        }

        _context.TodoItems.Remove(todoItem);
        await _context.SaveChangesAsync();

        return NoContent();
    }

    private bool TodoItemExists(long id)
    {
        return _context.TodoItems.Any(e => e.Id == id);
    }

    private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
       new TodoItemDTO
       {
           Id = todoItem.Id,
           Name = todoItem.Name,
           IsComplete = todoItem.IsComplete
       };
}

Sprawdź, czy nie możesz publikować ani pobierać pola wpisu tajnego.

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

Zobacz Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core przy użyciu języka JavaScript.

Seria wideo internetowego interfejsu API

Zobacz wideo: seria dla początkujących: internetowe interfejsy API.

Niezawodne wzorce aplikacji internetowej

Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji, zobacz Niezawodny wzorzecaplikacji internetowej for.NET YouTube.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Szybki start: wdrażanie aplikacji internetowej ASP.NET.

Dodatkowe zasoby

Wyświetl lub pobierz przykładowy kod dla tego samouczka. Zobacz , jak pobrać.

Aby uzyskać więcej informacji, zobacz następujące zasoby:

W tym samouczku przedstawiono podstawy tworzenia internetowego interfejsu API opartego na kontrolerze, który używa bazy danych. Innym podejściem do tworzenia interfejsów API w środowisku ASP.NET Core jest utworzenie minimalnych interfejsów API. Aby uzyskać pomoc dotyczącą wybierania między minimalnymi interfejsami API i interfejsami API opartymi na kontrolerach, zobacz Omówienie interfejsów API. Aby zapoznać się z samouczkiem dotyczącym tworzenia minimalnego interfejsu API, zobacz Samouczek: tworzenie minimalnego interfejsu API przy użyciu platformy ASP.NET Core.

Omówienie

Ten samouczek tworzy następujący interfejs API:

Interfejs API opis Treść żądania Treść odpowiedzi
GET /api/todoitems Pobieranie wszystkich elementów do wykonania Brak Tablica elementów do wykonania
GET /api/todoitems/{id} Pobieranie elementu według identyfikatora Brak Element do wykonania
POST /api/todoitems Dodawanie nowego elementu Element do wykonania Element do wykonania
PUT /api/todoitems/{id} Aktualizowanie istniejącego elementu Element do wykonania Brak
DELETE /api/todoitems/{id}     Usuwanie elementu Brak Brak

Na poniższym diagramie przedstawiono projekt aplikacji.

Klient jest reprezentowany przez pole po lewej stronie. Przesyła żądanie i odbiera odpowiedź z aplikacji, pole narysowane po prawej stronie. W polu aplikacji trzy pola reprezentują kontroler, model i warstwę dostępu do danych. Żądanie jest wprowadzane do kontrolera aplikacji, a operacje odczytu/zapisu są wykonywane między kontrolerem a warstwą dostępu do danych. Model jest serializowany i zwracany do klienta w odpowiedzi.

Wymagania wstępne

Tworzenie projektu internetowego

  • W menu Plik wybierz pozycję Nowy>projekt.
  • Wprowadź internetowy interfejs API w polu wyszukiwania.
  • Wybierz szablon internetowego interfejsu API platformy ASP.NET Core i wybierz pozycję Dalej.
  • W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę TodoApi i wybierz pozycję Dalej.
  • W oknie dialogowym Dodatkowe informacje:
    • Upewnij się, że platforma .NET 7.0 (lub nowsza).
    • Upewnij się, że pole wyboru Użyj kontrolerów (usuń zaznaczenie pola wyboru, aby używać minimalnych interfejsów API) jest zaznaczone.
    • Wybierz pozycję Utwórz.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Testowanie projektu

Szablon projektu tworzy interfejs API z obsługą WeatherForecast struktury Swagger.

Naciśnij klawisze Ctrl+F5, aby uruchomić bez debugera.

Program Visual Studio wyświetla następujące okno dialogowe, gdy projekt nie jest jeszcze skonfigurowany do używania protokołu SSL:

Ten projekt jest skonfigurowany do używania protokołu SSL. Aby uniknąć ostrzeżeń SSL w przeglądarce, możesz zaufać certyfikatowi z podpisem własnym wygenerowanemu przez usługę IIS Express. Czy chcesz ufać certyfikatowi SSL usług IIS Express?

Wybierz pozycję Tak , jeśli ufasz certyfikatowi SSL usług IIS Express.

Zostanie wyświetlone następujące okno dialogowe:

Okno dialogowe ostrzeżenia o zabezpieczeniach

Wybierz pozycję Tak, jeśli wyrażasz zgodę na zaufanie certyfikatowi programistycznemu.

Aby uzyskać informacje na temat zaufania przeglądarce Firefox, zobacz Błąd certyfikatu przeglądarki Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.

Program Visual Studio uruchamia domyślną przeglądarkę i przechodzi do https://localhost:<port>/swagger/index.htmllokalizacji , gdzie <port> jest losowo wybranym numerem portu.

Zostanie wyświetlona strona /swagger/index.html struktury Swagger. Wybierz pozycję GET Try it out>Execute (Pobierz>, wypróbuj wykonanie). Zostanie wyświetlona strona:

  • Polecenie Curl w celu przetestowania interfejsu API WeatherForecast.
  • Adres URL do przetestowania interfejsu API WeatherForecast.
  • Kod odpowiedzi, treść i nagłówki.
  • Pole listy rozwijanej z typami multimediów oraz przykładową wartością i schematem.

Jeśli strona struktury Swagger nie jest wyświetlana, zobacz ten problem z usługą GitHub.

Narzędzie Swagger służy do generowania przydatnej dokumentacji i stron pomocy dla internetowych interfejsów API. Ten samouczek koncentruje się na tworzeniu internetowego interfejsu API. Aby uzyskać więcej informacji na temat struktury Swagger, zobacz dokumentację internetowego interfejsu API platformy ASP.NET Core za pomocą programu Swagger/OpenAPI.

Skopiuj i wklej adres URL żądania w przeglądarce: https://localhost:<port>/weatherforecast

JSZwracany jest komunikat ON podobny do poniższego przykładu:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Dodawanie klasy modelu

Model to zestaw klas reprezentujących dane, którymi zarządza aplikacja. Model dla tej aplikacji jest klasą TodoItem .

  • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt. Wybierz pozycję Dodaj>nowy folder. Nadaj folderowi Modelsnazwę .
  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoItem i wybierz pozycję Dodaj.
  • Zastąp kod szablonu następującym kodem:
namespace TodoApi.Models;

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Właściwość Id działa jako unikatowy klucz w relacyjnej bazie danych.

Klasy modeli mogą znajdować się w dowolnym miejscu w projekcie, ale Models folder jest używany zgodnie z konwencją.

Dodawanie kontekstu bazy danych

Kontekst bazy danych jest klasą główną, która koordynuje funkcje programu Entity Framework dla modelu danych. Ta klasa jest tworzona przez wyprowadzanie z Microsoft.EntityFrameworkCore.DbContext klasy .

Dodawanie pakietów NuGet

  • W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > Zarządzaj pakietami NuGet dla rozwiązania.
  • Wybierz kartę Przeglądaj , a następnie wprowadź Microsoft.EntityFrameworkCore.InMemory ciąg w polu wyszukiwania.
  • Wybierz Microsoft.EntityFrameworkCore.InMemory w okienku po lewej stronie.
  • Zaznacz pole wyboru Projekt w okienku po prawej stronie, a następnie wybierz pozycję Zainstaluj.

Dodawanie kontekstu bazy danych TodoContext

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoContext i kliknij przycisk Dodaj.
  • Wprowadź następujące kod:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models;
    
    public class TodoContext : DbContext
    {
        public TodoContext(DbContextOptions<TodoContext> options)
            : base(options)
        {
        }
    
        public DbSet<TodoItem> TodoItems { get; set; } = null!;
    }
    

Rejestrowanie kontekstu bazy danych

W ASP.NET Core usługi, takie jak kontekst bazy danych, muszą być zarejestrowane w kontenerze wstrzykiwania zależności (DI). Kontener udostępnia usługę kontrolerom.

Zaktualizuj Program.cs za pomocą następującego wyróżnionego kodu:

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Powyższy kod ma następujące działanie:

  • Dodaje using dyrektywy.
  • Dodaje kontekst bazy danych do kontenera DI.
  • Określa, że kontekst bazy danych będzie używać bazy danych w pamięci.

Tworzenie szkieletu kontrolera

  • Kliknij prawym przyciskiem myszy folder Controllers .

  • Wybierz pozycję Dodaj>nowy element szkieletowy.

  • Wybierz pozycję Kontroler interfejsu API z akcjami przy użyciu platformy Entity Framework, a następnie wybierz pozycję Dodaj.

  • W oknie dialogowym Dodawanie kontrolera interfejsu API z akcjami przy użyciu programu Entity Framework :

    • Wybierz pozycję TodoItem (TodoApi.Models) w klasie Model.
    • Wybierz pozycję TodoContext (TodoApi.Models) w klasie Kontekst danych.
    • Wybierz Dodaj.

    Jeśli operacja tworzenia szkieletu nie powiedzie się, wybierz pozycję Dodaj , aby spróbować utworzyć szkielet po raz drugi.

Wygenerowany kod:

Szablony ASP.NET Core dla:

  • Kontrolery z widokami znajdują się [action] w szablonie trasy.
  • Kontrolery interfejsów API nie są uwzględniane [action] w szablonie trasy.

[action] Jeśli token nie znajduje się w szablonie trasy, nazwa akcji (nazwa metody) nie jest uwzględniona w punkcie końcowym. Oznacza to, że skojarzona nazwa metody akcji nie jest używana w pasującej trasie.

Aktualizowanie metody PostTodoItem create

Zaktualizuj instrukcję return w elemecie PostTodoItem , aby użyć operatora nameof :

[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //    return CreatedAtAction("PostTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(PostTodoItem), new { id = todoItem.Id }, todoItem);
}

Powyższy kod jest metodą wskazaną HTTP POST[HttpPost] przez atrybut . Metoda pobiera wartość TodoItem z treści żądania HTTP.

Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

Metoda CreatedAtAction:

  • Zwraca kod stanu HTTP 201, jeśli się powiedzie. HTTP 201 to standardowa odpowiedź dla HTTP POST metody, która tworzy nowy zasób na serwerze.
  • Dodaje nagłówek Location do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonego elementu do wykonania. Aby uzyskać więcej informacji, zobacz 10.2.2 201 Created (Utworzono 10.2.2 201).
  • Odwołuje się do akcji w PostTodoItem celu utworzenia Location identyfikatora URI nagłówka. Słowo kluczowe języka C# nameof służy do unikania kodowania na stałe nazwy akcji w wywołaniu CreatedAtAction .

Test PostTodoItem

  • Naciśnij klawisze Ctrl+F5, aby uruchomić aplikację.

  • W oknie przeglądarki struktury Swagger wybierz pozycję POST /api/TodoItems, a następnie wybierz pozycję Wypróbuj.

  • W oknie Wprowadzanie treści żądania zaktualizuj wartość JSWŁ. Przykład:

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • Wybierz przycisk Wykonaj.

    Swagger POST

Testowanie identyfikatora URI nagłówka lokalizacji

W poprzednim wpisie interfejs użytkownika struktury Swagger wyświetla nagłówek lokalizacji w obszarze Nagłówki odpowiedzi. Na przykład location: https://localhost:7260/api/TodoItems/1. Nagłówek lokalizacji zawiera identyfikator URI utworzonego zasobu.

Aby przetestować nagłówek lokalizacji:

  • W oknie przeglądarki struktury Swagger wybierz pozycję GET /api/TodoItems/{id}, a następnie wybierz pozycję Wypróbuj.

  • Wprowadź 1 w polu wejściowym id , a następnie wybierz pozycję Wykonaj.

    Swagger GET

Badanie metod GET

Zaimplementowano dwa punkty końcowe GET:

  • GET /api/todoitems
  • GET /api/todoitems/{id}

W poprzedniej sekcji przedstawiono przykład /api/todoitems/{id} trasy.

Postępuj zgodnie z instrukcjami POST , aby dodać kolejny element zadania do wykonania, a następnie przetestuj /api/todoitems trasę przy użyciu struktury Swagger.

Ta aplikacja używa bazy danych w pamięci. Jeśli aplikacja zostanie zatrzymana i uruchomiona, powyższe żądanie GET nie zwróci żadnych danych. Jeśli żadne dane nie są zwracane, dane POST do aplikacji.

Routing i ścieżki adresów URL

Atrybut [HttpGet] określa metodę, która odpowiada na HTTP GET żądanie. Ścieżka adresu URL dla każdej metody jest skonstruowana w następujący sposób:

  • Zacznij od ciągu szablonu w atrybucie kontrolera Route :

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Zastąp [controller] ciąg nazwą kontrolera, który zgodnie z konwencją jest nazwą klasy kontrolera minus sufiksem "Kontroler". W tym przykładzie nazwa klasy kontrolera to TodoItemsController, więc nazwa kontrolera to "TodoItems". routing ASP.NET Core jest niewrażliwy na wielkość liter.

  • [HttpGet] Jeśli atrybut ma szablon trasy (na przykład [HttpGet("products")]), dołącz go do ścieżki. Ten przykład nie używa szablonu. Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

W poniższej GetTodoItem metodzie "{id}" jest zmienną zastępczą unikatowego identyfikatora elementu do wykonania. Po GetTodoItem wywołaniu wartość "{id}" w adresie URL jest udostępniana metodzie w parametrze id .

[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Wartości zwracane

Zwracany GetTodoItems typ metod i GetTodoItem to ActionResult<T>. ASP.NET Core automatycznie serializuje obiekt włJS. i zapisuje wartość JSON w treści komunikatu odpowiedzi. Kod odpowiedzi dla tego typu zwracanego to 200 OK, zakładając, że nie ma żadnych nieobsługiwane wyjątki. Nieobsługiwane wyjątki są tłumaczone na błędy 5xx.

ActionResult typy zwracane mogą reprezentować szeroką gamę kodów stanu HTTP. Na przykład GetTodoItem może zwrócić dwie różne wartości stanu:

  • Jeśli żaden element nie pasuje do żądanego identyfikatora, metoda zwraca kod błędu stanuNotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią JSodpowiedzi ON. Zwracanie item wyników w HTTP 200 odpowiedzi.

Metoda PutTodoItem

Przeanalizuj metodę PutTodoItem:

[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem jest podobny do PostTodoItemelementu , z wyjątkiem tego, że używa metody HTTP PUT. Odpowiedź to 204 (brak zawartości). Zgodnie ze specyfikacją PUT PROTOKOŁU HTTP żądanie wymaga od klienta wysłania całej zaktualizowanej jednostki, a nie tylko zmian. Aby obsługiwać aktualizacje częściowe, użyj poprawki HTTP PATCH.

Testowanie metody PutTodoItem

W tym przykładzie użyto bazy danych w pamięci, która musi zostać zainicjowana przy każdym uruchomieniu aplikacji. Przed wykonaniem wywołania PUT musi istnieć element w bazie danych. Wywołaj metodę GET, aby upewnić się, że istnieje element w bazie danych przed wykonaniem wywołania PUT.

Za pomocą interfejsu użytkownika struktury Swagger użyj przycisku PUT, aby zaktualizować TodoItem identyfikator o identyfikatorze = 1 i ustawić jego nazwę na "feed fish". Zwróć uwagę, że odpowiedź to HTTP 204 No Content.

Metoda DeleteTodoItem

Przeanalizuj metodę DeleteTodoItem:

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

Testowanie metody DeleteTodoItem

Użyj interfejsu użytkownika struktury Swagger, aby usunąć identyfikator TodoItem o identyfikatorze = 1. Zwróć uwagę, że odpowiedź to HTTP 204 No Content.

Testowanie za pomocą polecenia http-repl, Postman lub curl

Protokół http-repl, Postman i curl są często używane do testowania interfejsów API. Narzędzie Swagger używa curl polecenia i wyświetla curl przesłane polecenie.

Aby uzyskać instrukcje dotyczące tych narzędzi, zobacz następujące linki:

Aby uzyskać więcej informacji na temat http-replusługi , zobacz Testowanie internetowych interfejsów API za pomocą protokołu HttpRepl.

Zapobieganie nadmiernemu delegowaniu

Obecnie przykładowa aplikacja uwidacznia cały TodoItem obiekt. Aplikacje produkcyjne zwykle ograniczają dane wejściowe i zwracane przy użyciu podzestawu modelu. Istnieje wiele powodów, dla których jest to ważne. Podzbiór modelu jest zwykle nazywany obiektem transferu danych (DTO), modelem wejściowym lub modelem widoku. Cel DTO jest używany w tym samouczku.

DTO może służyć do:

  • Zapobiegaj nadmiernemu delegowaniu.
  • Ukryj właściwości, których klienci nie powinni wyświetlać.
  • Pomiń niektóre właściwości, aby zmniejszyć rozmiar ładunku.
  • Spłaszczane wykresy obiektów zawierające zagnieżdżone obiekty. Spłaszczone grafy obiektów mogą być wygodniejsze dla klientów.

Aby zademonstrować podejście DTO, zaktualizuj klasę TodoItem tak, aby zawierała pole wpisu tajnego:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
        public string? Secret { get; set; }
    }
}

Pole wpisu tajnego musi być ukryte w tej aplikacji, ale aplikacja administracyjna może ją uwidocznić.

Sprawdź, czy możesz opublikować i pobrać pole wpisu tajnego.

Tworzenie modelu DTO:

namespace TodoApi.Models;

public class TodoItemDTO
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Zaktualizuj element , aby użyć polecenia TodoItemsControllerTodoItemDTO:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi.Controllers;

[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
{
    private readonly TodoContext _context;

    public TodoItemsController(TodoContext context)
    {
        _context = context;
    }

    // GET: api/TodoItems
    [HttpGet]
    public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
    {
        return await _context.TodoItems
            .Select(x => ItemToDTO(x))
            .ToListAsync();
    }

    // GET: api/TodoItems/5
    // <snippet_GetByID>
    [HttpGet("{id}")]
    public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            return NotFound();
        }

        return ItemToDTO(todoItem);
    }
    // </snippet_GetByID>

    // PUT: api/TodoItems/5
    // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
    // <snippet_Update>
    [HttpPut("{id}")]
    public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
    {
        if (id != todoDTO.Id)
        {
            return BadRequest();
        }

        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null)
        {
            return NotFound();
        }

        todoItem.Name = todoDTO.Name;
        todoItem.IsComplete = todoDTO.IsComplete;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
        {
            return NotFound();
        }

        return NoContent();
    }
    // </snippet_Update>

    // POST: api/TodoItems
    // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
    // <snippet_Create>
    [HttpPost]
    public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
    {
        var todoItem = new TodoItem
        {
            IsComplete = todoDTO.IsComplete,
            Name = todoDTO.Name
        };

        _context.TodoItems.Add(todoItem);
        await _context.SaveChangesAsync();

        return CreatedAtAction(
            nameof(GetTodoItem),
            new { id = todoItem.Id },
            ItemToDTO(todoItem));
    }
    // </snippet_Create>

    // DELETE: api/TodoItems/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null)
        {
            return NotFound();
        }

        _context.TodoItems.Remove(todoItem);
        await _context.SaveChangesAsync();

        return NoContent();
    }

    private bool TodoItemExists(long id)
    {
        return _context.TodoItems.Any(e => e.Id == id);
    }

    private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
       new TodoItemDTO
       {
           Id = todoItem.Id,
           Name = todoItem.Name,
           IsComplete = todoItem.IsComplete
       };
}

Sprawdź, czy nie możesz publikować ani pobierać pola wpisu tajnego.

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

Zobacz Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core przy użyciu języka JavaScript.

Seria wideo internetowego interfejsu API

Zobacz wideo: seria dla początkujących: internetowe interfejsy API.

Niezawodne wzorce aplikacji internetowej

Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji, zobacz Niezawodny wzorzecaplikacji internetowej for.NET YouTube.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Szybki start: wdrażanie aplikacji internetowej ASP.NET.

Dodatkowe zasoby

Wyświetl lub pobierz przykładowy kod dla tego samouczka. Zobacz , jak pobrać.

Aby uzyskać więcej informacji, zobacz następujące zasoby:

W tym samouczku przedstawiono podstawy tworzenia internetowego interfejsu API opartego na kontrolerze, który używa bazy danych. Innym podejściem do tworzenia interfejsów API w środowisku ASP.NET Core jest utworzenie minimalnych interfejsów API. Aby uzyskać pomoc dotyczącą wybierania między minimalnymi interfejsami API i interfejsami API opartymi na kontrolerach, zobacz Omówienie interfejsów API. Aby zapoznać się z samouczkiem dotyczącym tworzenia minimalnego interfejsu API, zobacz Samouczek: tworzenie minimalnego interfejsu API przy użyciu platformy ASP.NET Core.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Utwórz projekt internetowego interfejsu API.
  • Dodaj klasę modelu i kontekst bazy danych.
  • Tworzenie szkieletu kontrolera za pomocą metod CRUD.
  • Konfigurowanie routingu, ścieżek adresów URL i zwracanych wartości.
  • Wywoływanie internetowego interfejsu API za pomocą protokołu http-repl.

Na końcu masz internetowy interfejs API, który może zarządzać elementami "to-do" przechowywanymi w bazie danych.

Omówienie

Ten samouczek tworzy następujący interfejs API:

Interfejs API opis Treść żądania Treść odpowiedzi
GET /api/todoitems Pobieranie wszystkich elementów do wykonania Brak Tablica elementów do wykonania
GET /api/todoitems/{id} Pobieranie elementu według identyfikatora Brak Element do wykonania
POST /api/todoitems Dodawanie nowego elementu Element do wykonania Element do wykonania
PUT /api/todoitems/{id} Aktualizowanie istniejącego elementu Element do wykonania Brak
DELETE /api/todoitems/{id}     Usuwanie elementu Brak Brak

Na poniższym diagramie przedstawiono projekt aplikacji.

Klient jest reprezentowany przez pole po lewej stronie. Przesyła żądanie i odbiera odpowiedź z aplikacji, pole narysowane po prawej stronie. W polu aplikacji trzy pola reprezentują kontroler, model i warstwę dostępu do danych. Żądanie jest wprowadzane do kontrolera aplikacji, a operacje odczytu/zapisu są wykonywane między kontrolerem a warstwą dostępu do danych. Model jest serializowany i zwracany do klienta w odpowiedzi.

Wymagania wstępne

Tworzenie projektu internetowego

  • W menu Plik wybierz pozycję Nowy>projekt.
  • Wprowadź internetowy interfejs API w polu wyszukiwania.
  • Wybierz szablon internetowego interfejsu API platformy ASP.NET Core i wybierz pozycję Dalej.
  • W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę TodoApi i wybierz pozycję Dalej.
  • W oknie dialogowym Dodatkowe informacje:
    • Upewnij się, że platforma .NET 6.0 (obsługa długoterminowa).
    • Upewnij się, że pole wyboru Użyj kontrolerów (usuń zaznaczenie pola wyboru, aby używać minimalnych interfejsów API) jest zaznaczone.
    • Wybierz pozycję Utwórz.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Testowanie projektu

Szablon projektu tworzy interfejs API z obsługą WeatherForecast struktury Swagger.

Naciśnij klawisze Ctrl+F5, aby uruchomić bez debugera.

Program Visual Studio wyświetla następujące okno dialogowe, gdy projekt nie jest jeszcze skonfigurowany do używania protokołu SSL:

Ten projekt jest skonfigurowany do używania protokołu SSL. Aby uniknąć ostrzeżeń SSL w przeglądarce, możesz zaufać certyfikatowi z podpisem własnym wygenerowanemu przez usługę IIS Express. Czy chcesz ufać certyfikatowi SSL usług IIS Express?

Wybierz pozycję Tak , jeśli ufasz certyfikatowi SSL usług IIS Express.

Zostanie wyświetlone następujące okno dialogowe:

Okno dialogowe ostrzeżenia o zabezpieczeniach

Wybierz pozycję Tak, jeśli wyrażasz zgodę na zaufanie certyfikatowi programistycznemu.

Aby uzyskać informacje na temat zaufania przeglądarce Firefox, zobacz Błąd certyfikatu przeglądarki Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.

Program Visual Studio uruchamia domyślną przeglądarkę i przechodzi do https://localhost:<port>/swagger/index.htmllokalizacji , gdzie <port> jest losowo wybranym numerem portu.

Zostanie wyświetlona strona /swagger/index.html struktury Swagger. Wybierz pozycję GET Try it out>Execute (Pobierz>, wypróbuj wykonanie). Zostanie wyświetlona strona:

  • Polecenie Curl w celu przetestowania interfejsu API WeatherForecast.
  • Adres URL do przetestowania interfejsu API WeatherForecast.
  • Kod odpowiedzi, treść i nagłówki.
  • Pole listy rozwijanej z typami multimediów oraz przykładową wartością i schematem.

Jeśli strona struktury Swagger nie jest wyświetlana, zobacz ten problem z usługą GitHub.

Narzędzie Swagger służy do generowania przydatnej dokumentacji i stron pomocy dla internetowych interfejsów API. Ten samouczek koncentruje się na tworzeniu internetowego interfejsu API. Aby uzyskać więcej informacji na temat struktury Swagger, zobacz dokumentację internetowego interfejsu API platformy ASP.NET Core za pomocą programu Swagger/OpenAPI.

Skopiuj i wklej adres URL żądania w przeglądarce: https://localhost:<port>/weatherforecast

JSZwracany jest komunikat ON podobny do poniższego przykładu:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Aktualizowanie adresu launchUrl

W obszarze Właściwości\launch Ustawienia.json zaktualizuj plik launchUrl z "swagger" do :"api/todoitems"

"launchUrl": "api/todoitems",

Ponieważ program Swagger zostanie usunięty, poprzedni znacznik zmieni adres URL uruchomiony na metodę GET kontrolera dodanego w poniższych sekcjach.

Dodawanie klasy modelu

Model to zestaw klas reprezentujących dane, którymi zarządza aplikacja. Model dla tej aplikacji jest pojedynczą TodoItem klasą.

  • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt. Wybierz pozycję Dodaj>nowy folder. Nadaj folderowi Modelsnazwę .

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoItem i wybierz pozycję Dodaj.

  • Zastąp kod szablonu następującym kodem:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

Właściwość Id działa jako unikatowy klucz w relacyjnej bazie danych.

Klasy modeli mogą znajdować się w dowolnym miejscu w projekcie, ale Models folder jest używany zgodnie z konwencją.

Dodawanie kontekstu bazy danych

Kontekst bazy danych jest klasą główną, która koordynuje funkcje programu Entity Framework dla modelu danych. Ta klasa jest tworzona przez wyprowadzanie z Microsoft.EntityFrameworkCore.DbContext klasy .

Dodawanie pakietów NuGet

  • W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > Zarządzaj pakietami NuGet dla rozwiązania.
  • Wybierz kartę Przeglądaj , a następnie wprowadź Microsoft.EntityFrameworkCore.InMemory ciąg w polu wyszukiwania.
  • Wybierz Microsoft.EntityFrameworkCore.InMemory w okienku po lewej stronie.
  • Zaznacz pole wyboru Projekt w okienku po prawej stronie, a następnie wybierz pozycję Zainstaluj.

Dodawanie kontekstu bazy danych TodoContext

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoContext i kliknij przycisk Dodaj.
  • Wprowadź następujące kod:

    using Microsoft.EntityFrameworkCore;
    using System.Diagnostics.CodeAnalysis;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; } = null!;
        }
    }
    

Rejestrowanie kontekstu bazy danych

W ASP.NET Core usługi, takie jak kontekst bazy danych, muszą być zarejestrowane w kontenerze wstrzykiwania zależności (DI). Kontener udostępnia usługę kontrolerom.

Zaktualizuj Program.cs za pomocą następującego kodu:

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;


var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddDbContext<TodoContext>(opt =>
    opt.UseInMemoryDatabase("TodoList"));
//builder.Services.AddSwaggerGen(c =>
//{
//    c.SwaggerDoc("v1", new() { Title = "TodoApi", Version = "v1" });
//});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (builder.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    //app.UseSwagger();
    //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TodoApi v1"));
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Powyższy kod ma następujące działanie:

  • Usuwa wywołania struktury Swagger.
  • Usuwa nieużywane using dyrektywy.
  • Dodaje kontekst bazy danych do kontenera DI.
  • Określa, że kontekst bazy danych będzie używać bazy danych w pamięci.

Tworzenie szkieletu kontrolera

  • Kliknij prawym przyciskiem myszy folder Controllers .

  • Wybierz pozycję Dodaj>nowy element szkieletowy.

  • Wybierz pozycję Kontroler interfejsu API z akcjami przy użyciu platformy Entity Framework, a następnie wybierz pozycję Dodaj.

  • W oknie dialogowym Dodawanie kontrolera interfejsu API z akcjami przy użyciu programu Entity Framework :

    • Wybierz pozycję TodoItem (TodoApi.Models) w klasie Model.
    • Wybierz pozycję TodoContext (TodoApi.Models) w klasie Kontekst danych.
    • Wybierz Dodaj.

    Jeśli operacja tworzenia szkieletu nie powiedzie się, wybierz pozycję Dodaj , aby spróbować utworzyć szkielet po raz drugi.

Wygenerowany kod:

Szablony ASP.NET Core dla:

  • Kontrolery z widokami znajdują się [action] w szablonie trasy.
  • Kontrolery interfejsów API nie są uwzględniane [action] w szablonie trasy.

[action] Jeśli token nie znajduje się w szablonie trasy, nazwa akcji jest wykluczona z trasy. Oznacza to, że skojarzona nazwa metody akcji nie jest używana w pasującej trasie.

Aktualizowanie metody PostTodoItem create

Zaktualizuj instrukcję return w elemecie PostTodoItem , aby użyć operatora nameof :

[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //return CreatedAtAction("PostTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(PostTodoItem), new { id = todoItem.Id }, todoItem);
}

Powyższy kod jest metodą HTTP POST wskazaną [HttpPost] przez atrybut . Metoda pobiera wartość elementu to-do z treści żądania HTTP.

Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

Metoda CreatedAtAction:

  • Zwraca kod stanu HTTP 201, jeśli się powiedzie. HTTP 201 to standardowa odpowiedź dla metody HTTP POST, która tworzy nowy zasób na serwerze.
  • Dodaje nagłówek Location do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonego elementu do wykonania. Aby uzyskać więcej informacji, zobacz 10.2.2 201 Created (Utworzono 10.2.2 201).
  • Odwołuje się do akcji w GetTodoItem celu utworzenia Location identyfikatora URI nagłówka. Słowo kluczowe języka C# nameof służy do unikania kodowania na stałe nazwy akcji w wywołaniu CreatedAtAction .

Instalowanie protokołu http-repl

W tym samouczku użyto protokołu http-repl do przetestowania internetowego interfejsu API.

  • Uruchom następujące polecenie w wierszu polecenia:

    dotnet tool install -g Microsoft.dotnet-httprepl
    

    Uwaga

    Domyślnie architektura plików binarnych platformy .NET do zainstalowania reprezentuje obecnie uruchomioną architekturę systemu operacyjnego. Aby określić inną architekturę systemu operacyjnego, zobacz dotnet tool install, --arch option(Instalacja narzędzia dotnet). Aby uzyskać więcej informacji, zobacz problem z usługą GitHub dotnet/AspNetCore.Docs #29262.

  • Jeśli nie masz zainstalowanego zestawu .NET 6.0 SDK lub środowiska uruchomieniowego, zainstaluj środowisko uruchomieniowe platformy .NET 6.0.

Test PostTodoItem

  • Naciśnij klawisze Ctrl+F5, aby uruchomić aplikację.

  • Otwórz nowe okno terminalu i uruchom następujące polecenia. Jeśli aplikacja używa innego numeru portu, zastąp wartość 5001 w poleceniu httprepl numerem portu.

    httprepl https://localhost:5001/api/todoitems
    post -h Content-Type=application/json -c "{"name":"walk dog","isComplete":true}"
    

    Oto przykładowe dane wyjściowe tego polecenia:

    HTTP/1.1 201 Created
    Content-Type: application/json; charset=utf-8
    Date: Tue, 07 Sep 2021 20:39:47 GMT
    Location: https://localhost:5001/api/TodoItems/1
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
      "id": 1,
      "name": "walk dog",
      "isComplete": true
    }
    

Testowanie identyfikatora URI nagłówka lokalizacji

Aby przetestować nagłówek lokalizacji, skopiuj i wklej go do polecenia httprepl get .

W poniższym przykładzie założono, że nadal jesteś w sesji httprepl. Jeśli poprzednia sesja httprepl została zakończona, zastąp ciąg connect ciąg ciągiem httprepl w następujących poleceniach:

connect https://localhost:5001/api/todoitems/1
get

Oto przykładowe dane wyjściowe tego polecenia:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Tue, 07 Sep 2021 20:48:10 GMT
Server: Kestrel
Transfer-Encoding: chunked

{
  "id": 1,
  "name": "walk dog",
  "isComplete": true
}

Badanie metod GET

Zaimplementowano dwa punkty końcowe GET:

  • GET /api/todoitems
  • GET /api/todoitems/{id}

Właśnie pokazano przykład /api/todoitems/{id} trasy. Przetestuj /api/todoitems trasę:

connect https://localhost:5001/api/todoitems
get

Oto przykładowe dane wyjściowe tego polecenia:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Tue, 07 Sep 2021 20:59:21 GMT
Server: Kestrel
Transfer-Encoding: chunked

[
  {
    "id": 1,
    "name": "walk dog",
    "isComplete": true
  }
]

Tym razem JSzwracana wartość ON jest tablicą jednego elementu.

Ta aplikacja używa bazy danych w pamięci. Jeśli aplikacja zostanie zatrzymana i uruchomiona, powyższe żądanie GET nie zwróci żadnych danych. Jeśli żadne dane nie są zwracane, dane POST do aplikacji.

Routing i ścieżki adresów URL

Atrybut [HttpGet] określa metodę, która odpowiada na żądanie HTTP GET. Ścieżka adresu URL dla każdej metody jest skonstruowana w następujący sposób:

  • Zacznij od ciągu szablonu w atrybucie kontrolera Route :

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Zastąp [controller] ciąg nazwą kontrolera, który zgodnie z konwencją jest nazwą klasy kontrolera minus sufiksem "Kontroler". W tym przykładzie nazwa klasy kontrolera to TodoItemsController, więc nazwa kontrolera to "TodoItems". routing ASP.NET Core jest niewrażliwy na wielkość liter.

  • [HttpGet] Jeśli atrybut ma szablon trasy (na przykład [HttpGet("products")]), dołącz go do ścieżki. Ten przykład nie używa szablonu. Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

W poniższej GetTodoItem metodzie "{id}" jest zmienną zastępczą unikatowego identyfikatora elementu do wykonania. Po GetTodoItem wywołaniu wartość "{id}" w adresie URL jest udostępniana metodzie w parametrze id .

[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Wartości zwracane

Zwracany GetTodoItems typ metod i GetTodoItem to ActionResult<T>. ASP.NET Core automatycznie serializuje obiekt włJS. i zapisuje wartość JSON w treści komunikatu odpowiedzi. Kod odpowiedzi dla tego typu zwracanego to 200 OK, zakładając, że nie ma żadnych nieobsługiwane wyjątki. Nieobsługiwane wyjątki są tłumaczone na błędy 5xx.

ActionResult typy zwracane mogą reprezentować szeroką gamę kodów stanu HTTP. Na przykład GetTodoItem może zwrócić dwie różne wartości stanu:

  • Jeśli żaden element nie pasuje do żądanego identyfikatora, metoda zwraca kod błędu stanuNotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią JSodpowiedzi ON. Zwracanie item wyników w odpowiedzi HTTP 200.

Metoda PutTodoItem

Przeanalizuj metodę PutTodoItem:

[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem jest podobny do PostTodoItem, z tą różnicą, że używa protokołu HTTP PUT. Odpowiedź to 204 (brak zawartości). Zgodnie ze specyfikacją PROTOKOŁU HTTP żądanie PUT wymaga od klienta wysłania całej zaktualizowanej jednostki, a nie tylko zmian. Aby obsługiwać aktualizacje częściowe, użyj poprawki HTTP PATCH.

Jeśli w poniższej sekcji wystąpi błąd PutTodoItem , wywołaj metodę GET , aby upewnić się, że w bazie danych znajduje się element.

Testowanie metody PutTodoItem

W tym przykładzie użyto bazy danych w pamięci, która musi zostać zainicjowana przy każdym uruchomieniu aplikacji. Przed wykonaniem wywołania PUT musi istnieć element w bazie danych. Wywołaj metodę GET, aby upewnić się, że istnieje element w bazie danych przed wykonaniem wywołania PUT.

Zaktualizuj element do wykonania o identyfikatorze = 1 i ustaw jego nazwę na "feed fish":

connect https://localhost:5001/api/todoitems/1
put -h Content-Type=application/json -c "{"id":1,"name":"feed fish","isComplete":true}"

Oto przykładowe dane wyjściowe tego polecenia:

HTTP/1.1 204 No Content
Date: Tue, 07 Sep 2021 21:20:47 GMT
Server: Kestrel

Metoda DeleteTodoItem

Przeanalizuj metodę DeleteTodoItem:

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

Testowanie metody DeleteTodoItem

Usuń element do wykonania o identyfikatorze = 1:

connect https://localhost:5001/api/todoitems/1
delete

Oto przykładowe dane wyjściowe tego polecenia:

HTTP/1.1 204 No Content
Date: Tue, 07 Sep 2021 21:43:00 GMT
Server: Kestrel

Zapobieganie nadmiernemu delegowaniu

Obecnie przykładowa aplikacja uwidacznia cały TodoItem obiekt. Aplikacje produkcyjne zwykle ograniczają dane wejściowe i zwracane przy użyciu podzestawu modelu. Istnieje wiele powodów, dla których jest to ważne. Podzbiór modelu jest zwykle nazywany obiektem transferu danych (DTO), modelem wejściowym lub modelem widoku. Cel DTO jest używany w tym samouczku.

DTO może służyć do:

  • Zapobiegaj nadmiernemu delegowaniu.
  • Ukryj właściwości, których klienci nie powinni wyświetlać.
  • Pomiń niektóre właściwości, aby zmniejszyć rozmiar ładunku.
  • Spłaszczane wykresy obiektów zawierające zagnieżdżone obiekty. Spłaszczone grafy obiektów mogą być wygodniejsze dla klientów.

Aby zademonstrować podejście DTO, zaktualizuj klasę TodoItem tak, aby zawierała pole wpisu tajnego:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
        public string? Secret { get; set; }
    }
}

Pole wpisu tajnego musi być ukryte w tej aplikacji, ale aplikacja administracyjna może ją uwidocznić.

Sprawdź, czy możesz opublikować i pobrać pole wpisu tajnego.

Tworzenie modelu DTO:

namespace TodoApi.Models
{
    public class TodoItemDTO
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

Zaktualizuj element , aby użyć polecenia TodoItemsControllerTodoItemDTO:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;

        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }

        // GET: api/TodoItems
        [HttpGet]
        public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
        {
            return await _context.TodoItems
                .Select(x => ItemToDTO(x))
                .ToListAsync();
        }

        // GET: api/TodoItems/5
        [HttpGet("{id}")]
        public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
        {
            var todoItem = await _context.TodoItems.FindAsync(id);

            if (todoItem == null)
            {
                return NotFound();
            }

            return ItemToDTO(todoItem);
        }
        // PUT: api/TodoItems/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
        {
            if (id != todoItemDTO.Id)
            {
                return BadRequest();
            }

            var todoItem = await _context.TodoItems.FindAsync(id);
            if (todoItem == null)
            {
                return NotFound();
            }

            todoItem.Name = todoItemDTO.Name;
            todoItem.IsComplete = todoItemDTO.IsComplete;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
            {
                return NotFound();
            }

            return NoContent();
        }
        // POST: api/TodoItems
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<TodoItemDTO>> CreateTodoItem(TodoItemDTO todoItemDTO)
        {
            var todoItem = new TodoItem
            {
                IsComplete = todoItemDTO.IsComplete,
                Name = todoItemDTO.Name
            };

            _context.TodoItems.Add(todoItem);
            await _context.SaveChangesAsync();

            return CreatedAtAction(
                nameof(GetTodoItem),
                new { id = todoItem.Id },
                ItemToDTO(todoItem));
        }

        // DELETE: api/TodoItems/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteTodoItem(long id)
        {
            var todoItem = await _context.TodoItems.FindAsync(id);

            if (todoItem == null)
            {
                return NotFound();
            }

            _context.TodoItems.Remove(todoItem);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool TodoItemExists(long id)
        {
            return _context.TodoItems.Any(e => e.Id == id);
        }

        private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
            new TodoItemDTO
            {
                Id = todoItem.Id,
                Name = todoItem.Name,
                IsComplete = todoItem.IsComplete
            };
    }
}

Sprawdź, czy nie możesz publikować ani pobierać pola wpisu tajnego.

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

Zobacz Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core przy użyciu języka JavaScript.

Seria wideo internetowego interfejsu API

Zobacz wideo: seria dla początkujących: internetowe interfejsy API.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Szybki start: wdrażanie aplikacji internetowej ASP.NET.

Dodatkowe zasoby

Wyświetl lub pobierz przykładowy kod dla tego samouczka. Zobacz , jak pobrać.

Aby uzyskać więcej informacji, zobacz następujące zasoby:

W tym samouczku przedstawiono podstawy tworzenia internetowego interfejsu API opartego na kontrolerze, który używa bazy danych. Innym podejściem do tworzenia interfejsów API w środowisku ASP.NET Core jest utworzenie minimalnych interfejsów API. Aby uzyskać pomoc dotyczącą wybierania między minimalnymi interfejsami API i interfejsami API opartymi na kontrolerach, zobacz Omówienie interfejsów API. Aby zapoznać się z samouczkiem dotyczącym tworzenia minimalnego interfejsu API, zobacz Samouczek: tworzenie minimalnego interfejsu API przy użyciu platformy ASP.NET Core.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Utwórz projekt internetowego interfejsu API.
  • Dodaj klasę modelu i kontekst bazy danych.
  • Tworzenie szkieletu kontrolera za pomocą metod CRUD.
  • Konfigurowanie routingu, ścieżek adresów URL i zwracanych wartości.
  • Wywoływanie internetowego interfejsu API za pomocą narzędzia Postman.

Na końcu masz internetowy interfejs API, który może zarządzać elementami "to-do" przechowywanymi w bazie danych.

Omówienie

Ten samouczek tworzy następujący interfejs API:

Interfejs API opis Treść żądania Treść odpowiedzi
GET /api/todoitems Pobieranie wszystkich elementów do wykonania Brak Tablica elementów do wykonania
GET /api/todoitems/{id} Pobieranie elementu według identyfikatora Brak Element do wykonania
POST /api/todoitems Dodawanie nowego elementu Element do wykonania Element do wykonania
PUT /api/todoitems/{id} Aktualizowanie istniejącego elementu Element do wykonania Brak
DELETE /api/todoitems/{id}     Usuwanie elementu Brak Brak

Na poniższym diagramie przedstawiono projekt aplikacji.

Klient jest reprezentowany przez pole po lewej stronie. Przesyła żądanie i odbiera odpowiedź z aplikacji, pole narysowane po prawej stronie. W polu aplikacji trzy pola reprezentują kontroler, model i warstwę dostępu do danych. Żądanie jest wprowadzane do kontrolera aplikacji, a operacje odczytu/zapisu są wykonywane między kontrolerem a warstwą dostępu do danych. Model jest serializowany i zwracany do klienta w odpowiedzi.

Wymagania wstępne

Tworzenie projektu internetowego

  • W menu Plik wybierz pozycję Nowy>projekt.
  • Wybierz szablon internetowego interfejsu API platformy ASP.NET Core, a następnie kliknij przycisk Dalej.
  • Nadaj projektowi nazwę TodoApi i kliknij pozycję Utwórz.
  • W oknie dialogowym Tworzenie nowej aplikacji internetowej platformy ASP.NET Core upewnij się, że wybrano pozycję .NET Core i ASP.NET Core 5.0. Wybierz szablon interfejsu API i kliknij przycisk Utwórz.

Okno dialogowe nowy projekt programu VS

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Testowanie projektu

Szablon projektu tworzy interfejs API z obsługą WeatherForecast struktury Swagger.

Naciśnij klawisze Ctrl+F5, aby uruchomić bez debugera.

Program Visual Studio wyświetla następujące okno dialogowe, gdy projekt nie jest jeszcze skonfigurowany do używania protokołu SSL:

Ten projekt jest skonfigurowany do używania protokołu SSL. Aby uniknąć ostrzeżeń SSL w przeglądarce, możesz zaufać certyfikatowi z podpisem własnym wygenerowanemu przez usługę IIS Express. Czy chcesz ufać certyfikatowi SSL usług IIS Express?

Wybierz pozycję Tak , jeśli ufasz certyfikatowi SSL usług IIS Express.

Zostanie wyświetlone następujące okno dialogowe:

Okno dialogowe ostrzeżenia o zabezpieczeniach

Wybierz pozycję Tak, jeśli wyrażasz zgodę na zaufanie certyfikatowi programistycznemu.

Aby uzyskać informacje na temat zaufania przeglądarce Firefox, zobacz Błąd certyfikatu przeglądarki Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.

Program Visual Studio uruchamia:

  • Serwer sieci Web usług IIS Express.
  • Domyślna przeglądarka i przechodzi do https://localhost:<port>/swagger/index.htmllokalizacji , gdzie <port> jest losowo wybranym numerem portu.

Zostanie wyświetlona strona /swagger/index.html struktury Swagger. Wybierz pozycję GET Try it out>Execute (Pobierz>, wypróbuj wykonanie). Zostanie wyświetlona strona:

  • Polecenie Curl w celu przetestowania interfejsu API WeatherForecast.
  • Adres URL do przetestowania interfejsu API WeatherForecast.
  • Kod odpowiedzi, treść i nagłówki.
  • Pole listy rozwijanej z typami multimediów oraz przykładową wartością i schematem.

Jeśli strona struktury Swagger nie jest wyświetlana, zobacz ten problem z usługą GitHub.

Narzędzie Swagger służy do generowania przydatnej dokumentacji i stron pomocy dla internetowych interfejsów API. Ten samouczek koncentruje się na tworzeniu internetowego interfejsu API. Aby uzyskać więcej informacji na temat struktury Swagger, zobacz dokumentację internetowego interfejsu API platformy ASP.NET Core za pomocą programu Swagger/OpenAPI.

Skopiuj i wklej adres URL żądania w przeglądarce: https://localhost:<port>/weatherforecast

JSFunkcja ON podobna do następującej jest zwracana:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Aktualizowanie adresu launchUrl

W obszarze Właściwości\launch Ustawienia.json zaktualizuj plik launchUrl z "swagger" do :"api/todoitems"

"launchUrl": "api/todoitems",

Ponieważ program Swagger zostanie usunięty, poprzedni znacznik zmieni adres URL uruchomiony na metodę GET kontrolera dodanego w poniższych sekcjach.

Dodawanie klasy modelu

Model to zestaw klas reprezentujących dane, którymi zarządza aplikacja. Model dla tej aplikacji jest pojedynczą TodoItem klasą.

  • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt. Wybierz pozycję Dodaj>nowy folder. Nadaj folderowi Modelsnazwę .

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoItem i wybierz pozycję Dodaj.

  • Zastąp kod szablonu następującym kodem:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

Właściwość Id działa jako unikatowy klucz w relacyjnej bazie danych.

Klasy modeli mogą znajdować się w dowolnym miejscu w projekcie, ale Models folder jest używany zgodnie z konwencją.

Dodawanie kontekstu bazy danych

Kontekst bazy danych jest klasą główną, która koordynuje funkcje programu Entity Framework dla modelu danych. Ta klasa jest tworzona przez wyprowadzanie z Microsoft.EntityFrameworkCore.DbContext klasy .

Dodawanie pakietów NuGet

  • W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > Zarządzaj pakietami NuGet dla rozwiązania.
  • Wybierz kartę Przeglądaj , a następnie wprowadź Microsoft.EntityFrameworkCore.InMemory ciąg w polu wyszukiwania.
  • Wybierz Microsoft.EntityFrameworkCore.InMemory w okienku po lewej stronie.
  • Zaznacz pole wyboru Projekt w okienku po prawej stronie, a następnie wybierz pozycję Zainstaluj.

NuGet Package Manager

Dodawanie kontekstu bazy danych TodoContext

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoContext i kliknij przycisk Dodaj.
  • Wprowadź następujące kod:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

Rejestrowanie kontekstu bazy danych

W ASP.NET Core usługi, takie jak kontekst bazy danych, muszą być zarejestrowane w kontenerze wstrzykiwania zależności (DI). Kontener udostępnia usługę kontrolerom.

Zaktualizuj Startup.cs za pomocą następującego kodu:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddDbContext<TodoContext>(opt =>
                                               opt.UseInMemoryDatabase("TodoList"));
            //services.AddSwaggerGen(c =>
            //{
            //    c.SwaggerDoc("v1", new OpenApiInfo { Title = "TodoApi", Version = "v1" });
            //});
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //app.UseSwagger();
                //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TodoApi v1"));
            }

            app.UseHttpsRedirection();
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Powyższy kod ma następujące działanie:

  • Usuwa wywołania struktury Swagger.
  • Usuwa nieużywane using deklaracje.
  • Dodaje kontekst bazy danych do kontenera DI.
  • Określa, że kontekst bazy danych będzie używać bazy danych w pamięci.

Tworzenie szkieletu kontrolera

  • Kliknij prawym przyciskiem myszy folder Controllers .

  • Wybierz pozycję Dodaj>nowy element szkieletowy.

  • Wybierz pozycję Kontroler interfejsu API z akcjami przy użyciu platformy Entity Framework, a następnie wybierz pozycję Dodaj.

  • W oknie dialogowym Dodawanie kontrolera interfejsu API z akcjami przy użyciu programu Entity Framework :

    • Wybierz pozycję TodoItem (TodoApi.Models) w klasie Model.
    • Wybierz pozycję TodoContext (TodoApi.Models) w klasie Kontekst danych.
    • Wybierz Dodaj.

Wygenerowany kod:

Szablony ASP.NET Core dla:

  • Kontrolery z widokami znajdują się [action] w szablonie trasy.
  • Kontrolery interfejsów API nie są uwzględniane [action] w szablonie trasy.

[action] Jeśli token nie znajduje się w szablonie trasy, nazwa akcji jest wykluczona z trasy. Oznacza to, że skojarzona nazwa metody akcji nie jest używana w pasującej trasie.

Aktualizowanie metody PostTodoItem create

Zaktualizuj instrukcję return w elemecie PostTodoItem , aby użyć operatora nameof :

// POST: api/TodoItems
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //return CreatedAtAction("PostTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(PostTodoItem), new { id = todoItem.Id }, todoItem);
}

Powyższy kod jest metodą HTTP POST wskazaną [HttpPost] przez atrybut . Metoda pobiera wartość elementu to-do z treści żądania HTTP.

Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

Metoda CreatedAtAction:

  • Zwraca kod stanu HTTP 201, jeśli się powiedzie. HTTP 201 to standardowa odpowiedź dla metody HTTP POST, która tworzy nowy zasób na serwerze.
  • Dodaje nagłówek Location do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonego elementu do wykonania. Aby uzyskać więcej informacji, zobacz 201 Created (Utworzono 201).
  • Odwołuje się do akcji w GetTodoItem celu utworzenia Location identyfikatora URI nagłówka. Słowo kluczowe języka C# nameof służy do unikania kodowania na stałe nazwy akcji w wywołaniu CreatedAtAction .

Instalowanie narzędzia Postman

W tym samouczku do testowania internetowego interfejsu API jest używany narzędzie Postman.

  • Instalowanie narzędzia Postman
  • Uruchom aplikację internetową.
  • Uruchom narzędzie Postman.
  • Wyłącz weryfikację certyfikatu SSL:
    • Postman dla systemu Windows: wybierz pozycję Plik> Ustawienia (karta Ogólne), wyłącz weryfikację certyfikatu SSL.
    • Postman dla systemu macOS: wybierz pozycję Postman> Ustawienia (karta Ogólne), wyłącz weryfikację certyfikatu SSL.

      Ostrzeżenie

      Ponownie włącz weryfikację certyfikatu SSL po przetestowaniu kontrolera.

Testowanie elementu PostTodoItem za pomocą narzędzia Postman

  • Utwórz nowe żądanie.

  • Ustaw metodę HTTP na POST.

  • Ustaw identyfikator URI na https://localhost:<port>/api/todoitems. Na przykład https://localhost:5001/api/todoitems.

  • Wybierz kartę Treść.

  • Wybierz nieprzetworzone przycisk radiowy.

  • Ustaw typ na JSON (application/json).

  • W treści żądania wprowadź wł JS. dla elementu do wykonania:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • Wybierz Wyślij.

    Postman z żądaniem tworzenia

Testowanie identyfikatora URI nagłówka lokalizacji

Identyfikator URI nagłówka lokalizacji można przetestować w przeglądarce. Skopiuj i wklej identyfikator URI nagłówka lokalizacji w przeglądarce.

Aby przetestować w narzędziu Postman:

  • Wybierz kartę Nagłówki w okienku Odpowiedź .

  • Skopiuj wartość nagłówka Location :

    Karta Nagłówki konsoli Narzędzia Postman

  • Ustaw metodę HTTP na GET.

  • Ustaw identyfikator URI na https://localhost:<port>/api/todoitems/1. Na przykład https://localhost:5001/api/todoitems/1.

  • Wybierz Wyślij.

Badanie metod GET

Zaimplementowano dwa punkty końcowe GET:

  • GET /api/todoitems
  • GET /api/todoitems/{id}

Przetestuj aplikację, wywołując dwa punkty końcowe z przeglądarki lub narzędzia Postman. Na przykład:

  • https://localhost:5001/api/todoitems
  • https://localhost:5001/api/todoitems/1

Odpowiedź podobna do poniższej jest generowany przez wywołanie metody :GetTodoItems

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

Testowanie pobierania za pomocą narzędzia Postman

  • Utwórz nowe żądanie.
  • Ustaw metodę HTTP na GET.
  • Ustaw identyfikator URI żądania na https://localhost:<port>/api/todoitems. Na przykład https://localhost:5001/api/todoitems.
  • Ustaw widok dwa okienka w narzędziu Postman.
  • Wybierz Wyślij.

Ta aplikacja używa bazy danych w pamięci. Jeśli aplikacja zostanie zatrzymana i uruchomiona, powyższe żądanie GET nie zwróci żadnych danych. Jeśli żadne dane nie są zwracane, dane POST do aplikacji.

Routing i ścieżki adresów URL

Atrybut [HttpGet] określa metodę, która odpowiada na żądanie HTTP GET. Ścieżka adresu URL dla każdej metody jest skonstruowana w następujący sposób:

  • Zacznij od ciągu szablonu w atrybucie kontrolera Route :

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;
    
        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }
    
  • Zastąp [controller] ciąg nazwą kontrolera, który zgodnie z konwencją jest nazwą klasy kontrolera minus sufiksem "Kontroler". W tym przykładzie nazwa klasy kontrolera to TodoItemsController, więc nazwa kontrolera to "TodoItems". routing ASP.NET Core jest niewrażliwy na wielkość liter.

  • [HttpGet] Jeśli atrybut ma szablon trasy (na przykład [HttpGet("products")]), dołącz go do ścieżki. Ten przykład nie używa szablonu. Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

W poniższej GetTodoItem metodzie "{id}" jest zmienną zastępczą unikatowego identyfikatora elementu do wykonania. Po GetTodoItem wywołaniu wartość "{id}" w adresie URL jest udostępniana metodzie w parametrze id .

// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Wartości zwracane

Zwracany GetTodoItems typ metod i GetTodoItem to ActionResult<T>. ASP.NET Core automatycznie serializuje obiekt włJS. i zapisuje wartość JSON w treści komunikatu odpowiedzi. Kod odpowiedzi dla tego typu zwracanego to 200 OK, zakładając, że nie ma żadnych nieobsługiwane wyjątki. Nieobsługiwane wyjątki są tłumaczone na błędy 5xx.

ActionResult typy zwracane mogą reprezentować szeroką gamę kodów stanu HTTP. Na przykład GetTodoItem może zwrócić dwie różne wartości stanu:

  • Jeśli żaden element nie pasuje do żądanego identyfikatora, metoda zwraca kod błędu stanuNotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią JSodpowiedzi ON. Zwracanie item wyników w odpowiedzi HTTP 200.

Metoda PutTodoItem

Przeanalizuj metodę PutTodoItem:

// PUT: api/TodoItems/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem jest podobny do PostTodoItem, z tą różnicą, że używa protokołu HTTP PUT. Odpowiedź to 204 (brak zawartości). Zgodnie ze specyfikacją PROTOKOŁU HTTP żądanie PUT wymaga od klienta wysłania całej zaktualizowanej jednostki, a nie tylko zmian. Aby obsługiwać aktualizacje częściowe, użyj poprawki HTTP PATCH.

Jeśli wystąpi błąd podczas wywoływania PutTodoItemmetody , wywołaj metodę GET , aby upewnić się, że w bazie danych znajduje się element.

Testowanie metody PutTodoItem

W tym przykładzie użyto bazy danych w pamięci, która musi zostać zainicjowana przy każdym uruchomieniu aplikacji. Przed wykonaniem wywołania PUT musi istnieć element w bazie danych. Wywołaj metodę GET, aby upewnić się, że istnieje element w bazie danych przed wykonaniem wywołania PUT.

Zaktualizuj element do wykonania o identyfikatorze = 1 i ustaw jego nazwę na "feed fish":

  {
    "Id":1,
    "name":"feed fish",
    "isComplete":true
  }

Na poniższej ilustracji przedstawiono aktualizację narzędzia Postman:

Konsola narzędzia Postman przedstawiająca odpowiedź 204 (brak zawartości)

Metoda DeleteTodoItem

Przeanalizuj metodę DeleteTodoItem:

// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

Testowanie metody DeleteTodoItem

Użyj narzędzia Postman, aby usunąć element do wykonania:

  • Ustaw metodę na DELETE.
  • Ustaw identyfikator URI obiektu do usunięcia (na przykład https://localhost:5001/api/todoitems/1).
  • Wybierz Wyślij.

Zapobieganie nadmiernemu delegowaniu

Obecnie przykładowa aplikacja uwidacznia cały TodoItem obiekt. Aplikacje produkcyjne zwykle ograniczają dane wejściowe i zwracane przy użyciu podzestawu modelu. Istnieje wiele powodów, dla których jest to ważne. Podzbiór modelu jest zwykle nazywany obiektem transferu danych (DTO), modelem wejściowym lub modelem widoku. DTO jest używane w tym artykule.

DTO może służyć do:

  • Zapobiegaj nadmiernemu delegowaniu.
  • Ukryj właściwości, których klienci nie powinni wyświetlać.
  • Pomiń niektóre właściwości, aby zmniejszyć rozmiar ładunku.
  • Spłaszczane wykresy obiektów zawierające zagnieżdżone obiekty. Spłaszczone grafy obiektów mogą być wygodniejsze dla klientów.

Aby zademonstrować podejście DTO, zaktualizuj klasę TodoItem tak, aby zawierała pole wpisu tajnego:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
        public string Secret { get; set; }
    }
}

Pole wpisu tajnego musi być ukryte w tej aplikacji, ale aplikacja administracyjna może ją uwidocznić.

Sprawdź, czy możesz opublikować i pobrać pole wpisu tajnego.

Tworzenie modelu DTO:

public class TodoItemDTO
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
}

Zaktualizuj element , aby użyć polecenia TodoItemsControllerTodoItemDTO:

// GET: api/TodoItems
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
    return await _context.TodoItems
        .Select(x => ItemToDTO(x))
        .ToListAsync();
}

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

[HttpPut("{id}")]
public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
{
    if (id != todoItemDTO.Id)
    {
        return BadRequest();
    }

    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    todoItem.Name = todoItemDTO.Name;
    todoItem.IsComplete = todoItemDTO.IsComplete;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
    {
        return NotFound();
    }

    return NoContent();
}

[HttpPost]
public async Task<ActionResult<TodoItemDTO>> CreateTodoItem(TodoItemDTO todoItemDTO)
{
    var todoItem = new TodoItem
    {
        IsComplete = todoItemDTO.IsComplete,
        Name = todoItemDTO.Name
    };

    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    return CreatedAtAction(
        nameof(GetTodoItem),
        new { id = todoItem.Id },
        ItemToDTO(todoItem));
}

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

private bool TodoItemExists(long id) =>
     _context.TodoItems.Any(e => e.Id == id);

private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
    new TodoItemDTO
    {
        Id = todoItem.Id,
        Name = todoItem.Name,
        IsComplete = todoItem.IsComplete
    };

Sprawdź, czy nie możesz publikować ani pobierać pola wpisu tajnego.

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

Zobacz Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core przy użyciu języka JavaScript.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Szybki start: wdrażanie aplikacji internetowej ASP.NET.

Dodatkowe zasoby

Wyświetl lub pobierz przykładowy kod dla tego samouczka. Zobacz , jak pobrać.

Aby uzyskać więcej informacji, zobacz następujące zasoby:

W tym samouczku przedstawiono podstawy tworzenia internetowego interfejsu API opartego na kontrolerze, który używa bazy danych. Innym podejściem do tworzenia interfejsów API w środowisku ASP.NET Core jest utworzenie minimalnych interfejsów API. Aby uzyskać pomoc dotyczącą wybierania między minimalnymi interfejsami API i interfejsami API opartymi na kontrolerach, zobacz Omówienie interfejsów API. Aby zapoznać się z samouczkiem dotyczącym tworzenia minimalnego interfejsu API, zobacz Samouczek: tworzenie minimalnego interfejsu API przy użyciu platformy ASP.NET Core.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Utwórz projekt internetowego interfejsu API.
  • Dodaj klasę modelu i kontekst bazy danych.
  • Tworzenie szkieletu kontrolera za pomocą metod CRUD.
  • Konfigurowanie routingu, ścieżek adresów URL i zwracanych wartości.
  • Wywoływanie internetowego interfejsu API za pomocą narzędzia Postman.

Na końcu masz internetowy interfejs API, który może zarządzać elementami "to-do" przechowywanymi w bazie danych.

Omówienie

Ten samouczek tworzy następujący interfejs API:

Interfejs API opis Treść żądania Treść odpowiedzi
GET /api/todoitems Pobieranie wszystkich elementów do wykonania Brak Tablica elementów do wykonania
GET /api/todoitems/{id} Pobieranie elementu według identyfikatora Brak Element do wykonania
POST /api/todoitems Dodawanie nowego elementu Element do wykonania Element do wykonania
PUT /api/todoitems/{id} Aktualizowanie istniejącego elementu Element do wykonania Brak
DELETE /api/todoitems/{id}     Usuwanie elementu Brak Brak

Na poniższym diagramie przedstawiono projekt aplikacji.

Klient jest reprezentowany przez pole po lewej stronie. Przesyła żądanie i odbiera odpowiedź z aplikacji, pole narysowane po prawej stronie. W polu aplikacji trzy pola reprezentują kontroler, model i warstwę dostępu do danych. Żądanie jest wprowadzane do kontrolera aplikacji, a operacje odczytu/zapisu są wykonywane między kontrolerem a warstwą dostępu do danych. Model jest serializowany i zwracany do klienta w odpowiedzi.

Wymagania wstępne

Tworzenie projektu internetowego

  • W menu Plik wybierz pozycję Nowy>projekt.
  • Wybierz szablon ASP.NET Core Web Application i kliknij przycisk Dalej.
  • Nadaj projektowi nazwę TodoApi i kliknij pozycję Utwórz.
  • W oknie dialogowym Tworzenie nowej aplikacji internetowej platformy ASP.NET Core upewnij się, że wybrano pozycję .NET Core i ASP.NET Core 3.1. Wybierz szablon interfejsu API i kliknij przycisk Utwórz.

Okno dialogowe nowy projekt programu VS

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Testowanie interfejsu API

Szablon projektu tworzy WeatherForecast interfejs API. Wywołaj metodę Get z przeglądarki, aby przetestować aplikację.

Naciśnij klawisze Ctrl+F5, aby uruchomić aplikację. Program Visual Studio uruchamia przeglądarkę i przechodzi do https://localhost:<port>/weatherforecastlokalizacji , gdzie <port> jest losowo wybranym numerem portu.

Jeśli zostanie wyświetlone okno dialogowe z pytaniem, czy należy ufać certyfikatowi usługi IIS Express, wybierz pozycję Tak. W wyświetlonym oknie dialogowym Ostrzeżenie o zabezpieczeniach wybierz pozycję Tak.

JSFunkcja ON podobna do następującej jest zwracana:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Dodawanie klasy modelu

Model to zestaw klas reprezentujących dane, którymi zarządza aplikacja. Model dla tej aplikacji jest pojedynczą TodoItem klasą.

  • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt. Wybierz pozycję Dodaj>nowy folder. Nadaj folderowi Modelsnazwę .

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoItem i wybierz pozycję Dodaj.

  • Zastąp kod szablonu następującym kodem:

public class TodoItem
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
}

Właściwość Id działa jako unikatowy klucz w relacyjnej bazie danych.

Klasy modeli mogą znajdować się w dowolnym miejscu w projekcie, ale Models folder jest używany zgodnie z konwencją.

Dodawanie kontekstu bazy danych

Kontekst bazy danych jest klasą główną, która koordynuje funkcje programu Entity Framework dla modelu danych. Ta klasa jest tworzona przez wyprowadzanie z Microsoft.EntityFrameworkCore.DbContext klasy .

Dodawanie pakietów NuGet

  • W menu Narzędzia wybierz pozycję NuGet Menedżer pakietów > Zarządzaj pakietami NuGet dla rozwiązania.
  • Wybierz kartę Przeglądaj , a następnie wprowadź ciąg Microsoft.EntityFrameworkCore.InMemory w polu wyszukiwania.
  • Wybierz pozycję Microsoft.EntityFrameworkCore.InMemory w okienku po lewej stronie.
  • Zaznacz pole wyboru Projekt w okienku po prawej stronie, a następnie wybierz pozycję Zainstaluj.

NuGet Package Manager

Dodawanie kontekstu bazy danych TodoContext

  • Kliknij prawym przyciskiem Models myszy folder i wybierz polecenie Dodaj>klasę. Nadaj klasie nazwę TodoContext i kliknij przycisk Dodaj.
  • Wprowadź następujące kod:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

Rejestrowanie kontekstu bazy danych

W ASP.NET Core usługi, takie jak kontekst bazy danych, muszą być zarejestrowane w kontenerze wstrzykiwania zależności (DI). Kontener udostępnia usługę kontrolerom.

Zaktualizuj Startup.cs za pomocą następującego wyróżnionego kodu:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt =>
               opt.UseInMemoryDatabase("TodoList"));
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Powyższy kod ma następujące działanie:

  • Usuwa nieużywane using deklaracje.
  • Dodaje kontekst bazy danych do kontenera DI.
  • Określa, że kontekst bazy danych będzie używać bazy danych w pamięci.

Tworzenie szkieletu kontrolera

  • Kliknij prawym przyciskiem myszy folder Controllers .

  • Wybierz pozycję Dodaj>nowy element szkieletowy.

  • Wybierz pozycję Kontroler interfejsu API z akcjami przy użyciu platformy Entity Framework, a następnie wybierz pozycję Dodaj.

  • W oknie dialogowym Dodawanie kontrolera interfejsu API z akcjami przy użyciu programu Entity Framework :

    • Wybierz pozycję TodoItem (TodoApi.Models) w klasie Model.
    • Wybierz pozycję TodoContext (TodoApi.Models) w klasie Kontekst danych.
    • Wybierz Dodaj.

Wygenerowany kod:

Szablony ASP.NET Core dla:

  • Kontrolery z widokami znajdują się [action] w szablonie trasy.
  • Kontrolery interfejsów API nie są uwzględniane [action] w szablonie trasy.

[action] Jeśli token nie znajduje się w szablonie trasy, nazwa akcji jest wykluczona z trasy. Oznacza to, że skojarzona nazwa metody akcji nie jest używana w pasującej trasie.

Badanie metody Create PostTodoItem

Zastąp instrukcję return w elemencie PostTodoItem , aby użyć operatora nameof :

// POST: api/TodoItems
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //return CreatedAtAction("PostTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(PostTodoItem), new { id = todoItem.Id }, todoItem);
}

Powyższy kod jest metodą HTTP POST wskazaną [HttpPost] przez atrybut . Metoda pobiera wartość elementu to-do z treści żądania HTTP.

Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

Metoda CreatedAtAction:

  • Zwraca kod stanu HTTP 201, jeśli się powiedzie. HTTP 201 to standardowa odpowiedź dla metody HTTP POST, która tworzy nowy zasób na serwerze.
  • Dodaje nagłówek Location do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonego elementu do wykonania. Aby uzyskać więcej informacji, zobacz 201 Created (Utworzono 201).
  • Odwołuje się do akcji w GetTodoItem celu utworzenia Location identyfikatora URI nagłówka. Słowo kluczowe języka C# nameof służy do unikania kodowania na stałe nazwy akcji w wywołaniu CreatedAtAction .

Instalowanie narzędzia Postman

W tym samouczku do testowania internetowego interfejsu API jest używany narzędzie Postman.

  • Instalowanie narzędzia Postman
  • Uruchom aplikację internetową.
  • Uruchom narzędzie Postman.
  • Wyłącz weryfikację certyfikatu SSL:
    • Postman dla systemu Windows: Postman for Windows File> Ustawienia (karta Ogólne), wyłącz weryfikację certyfikatu SSL.
    • Postman dla systemu macOS: Postman dla programu Windows Postman> Ustawienia (karta Ogólne), wyłącz weryfikację certyfikatu SSL.

      Ostrzeżenie

      Ponownie włącz weryfikację certyfikatu SSL po przetestowaniu kontrolera.

Testowanie elementu PostTodoItem za pomocą narzędzia Postman

  • Utwórz nowe żądanie.

  • Ustaw metodę HTTP na POST.

  • Ustaw identyfikator URI na https://localhost:<port>/api/todoitems. Na przykład https://localhost:5001/api/todoitems.

  • Wybierz kartę Treść.

  • Wybierz nieprzetworzone przycisk radiowy.

  • Ustaw typ na JSON (application/json).

  • W treści żądania wprowadź wł JS. dla elementu do wykonania:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • Wybierz Wyślij.

    Postman z żądaniem tworzenia

Testowanie identyfikatora URI nagłówka lokalizacji za pomocą narzędzia Postman

  • Wybierz kartę Nagłówki w okienku Odpowiedź .

  • Skopiuj wartość nagłówka Location :

    Karta Nagłówki konsoli Narzędzia Postman

  • Ustaw metodę HTTP na GET.

  • Ustaw identyfikator URI na https://localhost:<port>/api/todoitems/1. Na przykład https://localhost:5001/api/todoitems/1.

  • Wybierz Wyślij.

Badanie metod GET

Te metody implementują dwa punkty końcowe GET:

  • GET /api/todoitems
  • GET /api/todoitems/{id}

Przetestuj aplikację, wywołując dwa punkty końcowe z przeglądarki lub narzędzia Postman. Na przykład:

  • https://localhost:5001/api/todoitems
  • https://localhost:5001/api/todoitems/1

Odpowiedź podobna do poniższej jest generowany przez wywołanie metody :GetTodoItems

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

Testowanie pobierania za pomocą narzędzia Postman

  • Utwórz nowe żądanie.
  • Ustaw metodę HTTP na GET.
  • Ustaw identyfikator URI żądania na https://localhost:<port>/api/todoitems. Na przykład https://localhost:5001/api/todoitems.
  • Ustaw widok dwa okienka w narzędziu Postman.
  • Wybierz Wyślij.

Ta aplikacja używa bazy danych w pamięci. Jeśli aplikacja zostanie zatrzymana i uruchomiona, powyższe żądanie GET nie zwróci żadnych danych. Jeśli żadne dane nie są zwracane, dane POST do aplikacji.

Routing i ścieżki adresów URL

Atrybut [HttpGet] określa metodę, która odpowiada na żądanie HTTP GET. Ścieżka adresu URL dla każdej metody jest skonstruowana w następujący sposób:

  • Zacznij od ciągu szablonu w atrybucie kontrolera Route :

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;
    
        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }
    
  • Zastąp [controller] ciąg nazwą kontrolera, który zgodnie z konwencją jest nazwą klasy kontrolera minus sufiksem "Kontroler". W tym przykładzie nazwa klasy kontrolera to TodoItemsController, więc nazwa kontrolera to "TodoItems". routing ASP.NET Core jest niewrażliwy na wielkość liter.

  • [HttpGet] Jeśli atrybut ma szablon trasy (na przykład [HttpGet("products")]), dołącz go do ścieżki. Ten przykład nie używa szablonu. Aby uzyskać więcej informacji, zobacz Routing atrybutów przy użyciu atrybutów Http[Verb].

W poniższej GetTodoItem metodzie "{id}" jest zmienną zastępczą unikatowego identyfikatora elementu do wykonania. Po GetTodoItem wywołaniu wartość "{id}" w adresie URL jest udostępniana metodzie w parametrze id .

// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Wartości zwracane

Zwracany GetTodoItems typ metod i GetTodoItem to ActionResult<T>. ASP.NET Core automatycznie serializuje obiekt włJS. i zapisuje wartość JSON w treści komunikatu odpowiedzi. Kod odpowiedzi dla tego typu zwracanego to 200, zakładając, że nie ma żadnych nieobsługiwane wyjątki. Nieobsługiwane wyjątki są tłumaczone na błędy 5xx.

ActionResult typy zwracane mogą reprezentować szeroką gamę kodów stanu HTTP. Na przykład GetTodoItem może zwrócić dwie różne wartości stanu:

  • Jeśli żaden element nie pasuje do żądanego identyfikatora, metoda zwraca kod błędu 404 NotFound .
  • W przeciwnym razie metoda zwraca wartość 200 z treścią JSodpowiedzi ON. Zwracanie item wyników w odpowiedzi HTTP 200.

Metoda PutTodoItem

Przeanalizuj metodę PutTodoItem:

// PUT: api/TodoItems/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem jest podobny do PostTodoItem, z tą różnicą, że używa protokołu HTTP PUT. Odpowiedź to 204 (brak zawartości). Zgodnie ze specyfikacją PROTOKOŁU HTTP żądanie PUT wymaga od klienta wysłania całej zaktualizowanej jednostki, a nie tylko zmian. Aby obsługiwać aktualizacje częściowe, użyj poprawki HTTP PATCH.

Jeśli wystąpi błąd podczas wywoływania PutTodoItemmetody , wywołaj metodę GET , aby upewnić się, że w bazie danych znajduje się element.

Testowanie metody PutTodoItem

W tym przykładzie użyto bazy danych w pamięci, która musi zostać zainicjowana przy każdym uruchomieniu aplikacji. Przed wykonaniem wywołania PUT musi istnieć element w bazie danych. Wywołaj metodę GET, aby upewnić się, że istnieje element w bazie danych przed wykonaniem wywołania PUT.

Zaktualizuj element to-do o identyfikatorze = 1 i ustaw jego nazwę na "ryby paszowe":

  {
    "id":1,
    "name":"feed fish",
    "isComplete":true
  }

Na poniższej ilustracji przedstawiono aktualizację narzędzia Postman:

Konsola narzędzia Postman przedstawiająca odpowiedź 204 (brak zawartości)

Metoda DeleteTodoItem

Przeanalizuj metodę DeleteTodoItem:

// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<ActionResult<TodoItem>> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return todoItem;
}

Testowanie metody DeleteTodoItem

Użyj narzędzia Postman, aby usunąć element do wykonania:

  • Ustaw metodę na DELETE.
  • Ustaw identyfikator URI obiektu do usunięcia (na przykład https://localhost:5001/api/todoitems/1).
  • Wybierz Wyślij.

Zapobieganie nadmiernemu delegowaniu

Obecnie przykładowa aplikacja uwidacznia cały TodoItem obiekt. Aplikacje produkcyjne zwykle ograniczają dane wejściowe i zwracane przy użyciu podzestawu modelu. Istnieje wiele powodów, dla których jest to ważne. Podzbiór modelu jest zwykle nazywany obiektem transferu danych (DTO), modelem wejściowym lub modelem widoku. DTO jest używane w tym artykule.

DTO może służyć do:

  • Zapobiegaj nadmiernemu delegowaniu.
  • Ukryj właściwości, których klienci nie powinni wyświetlać.
  • Pomiń niektóre właściwości, aby zmniejszyć rozmiar ładunku.
  • Spłaszczane wykresy obiektów zawierające zagnieżdżone obiekty. Spłaszczone grafy obiektów mogą być wygodniejsze dla klientów.

Aby zademonstrować podejście DTO, zaktualizuj klasę TodoItem tak, aby zawierała pole wpisu tajnego:

public class TodoItem
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
    public string Secret { get; set; }
}

Pole wpisu tajnego musi być ukryte w tej aplikacji, ale aplikacja administracyjna może ją uwidocznić.

Sprawdź, czy możesz opublikować i pobrać pole wpisu tajnego.

Tworzenie modelu DTO:

public class TodoItemDTO
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
}

Zaktualizuj element , aby użyć polecenia TodoItemsControllerTodoItemDTO:

    [HttpGet]
    public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
    {
        return await _context.TodoItems
            .Select(x => ItemToDTO(x))
            .ToListAsync();
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            return NotFound();
        }

        return ItemToDTO(todoItem);
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
    {
        if (id != todoItemDTO.Id)
        {
            return BadRequest();
        }

        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null)
        {
            return NotFound();
        }

        todoItem.Name = todoItemDTO.Name;
        todoItem.IsComplete = todoItemDTO.IsComplete;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
        {
            return NotFound();
        }

        return NoContent();
    }

    [HttpPost]
    public async Task<ActionResult<TodoItemDTO>> CreateTodoItem(TodoItemDTO todoItemDTO)
    {
        var todoItem = new TodoItem
        {
            IsComplete = todoItemDTO.IsComplete,
            Name = todoItemDTO.Name
        };

        _context.TodoItems.Add(todoItem);
        await _context.SaveChangesAsync();

        return CreatedAtAction(
            nameof(GetTodoItem),
            new { id = todoItem.Id },
            ItemToDTO(todoItem));
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            return NotFound();
        }

        _context.TodoItems.Remove(todoItem);
        await _context.SaveChangesAsync();

        return NoContent();
    }

    private bool TodoItemExists(long id) =>
         _context.TodoItems.Any(e => e.Id == id);

    private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
        new TodoItemDTO
        {
            Id = todoItem.Id,
            Name = todoItem.Name,
            IsComplete = todoItem.IsComplete
        };       
}

Sprawdź, czy nie możesz publikować ani pobierać pola wpisu tajnego.

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

Zobacz Samouczek: wywoływanie internetowego interfejsu API platformy ASP.NET Core przy użyciu języka JavaScript.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Publikowanie na platformie Azure

Aby uzyskać informacje na temat wdrażania na platformie Azure, zobacz Szybki start: wdrażanie aplikacji internetowej ASP.NET.

Dodatkowe zasoby

Wyświetl lub pobierz przykładowy kod dla tego samouczka. Zobacz , jak pobrać.

Aby uzyskać więcej informacji, zobacz następujące zasoby: