Udostępnij za pośrednictwem


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ą, zobacz wersję tego artykułu platformy .NET 9.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). 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ą, zobacz wersję tego artykułu platformy .NET 9.

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

Zwracany jest kod JSON podobny do następującego 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 Controllers myszy folder.

  • Wybierz Dodaj>New Scaffolded Item.

  • 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("GetTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(GetTodoItem), 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 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 .

Test PostTodoItem

  • Naciśnij 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 kod JSON. Na 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 zwraca ż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 formacie JSON i zapisuje kod 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 stanu NotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią odpowiedzi JSON. 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 TodoItemsController TodoItemDTO:

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

for.NET Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, zapoznaj się ze wskazówkami dotyczącymi tworzenia nowoczesnej, niezawodnej, wydajnej i skalowalnej aplikacji platformy ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji.

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 Connect 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 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 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

Zwracany jest kod JSON podobny do następującego 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 Controllers myszy folder.

  • Wybierz Dodaj>New Scaffolded Item.

  • 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("GetTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(GetTodoItem), 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 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 .

Test PostTodoItem

  • Naciśnij 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 kod JSON. Na 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 zwraca ż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 formacie JSON i zapisuje kod 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 stanu NotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią odpowiedzi JSON. 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 TodoItemsController TodoItemDTO:

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

for.NET Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, zapoznaj się ze wskazówkami dotyczącymi tworzenia nowoczesnej, niezawodnej, wydajnej i skalowalnej aplikacji platformy ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji.

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 Connect 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 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 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

Zwracany jest kod JSON podobny do następującego 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 Controllers myszy folder.

  • Wybierz Dodaj>New Scaffolded Item.

  • 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("GetTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(GetTodoItem), 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 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 .

Test PostTodoItem

  • Naciśnij 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 kod JSON. Na 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 zwraca ż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 formacie JSON i zapisuje kod 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 stanu NotFound 404.
  • W przeciwnym razie metoda zwraca wartość 200 z treścią odpowiedzi JSON. 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 TodoItemsController TodoItemDTO:

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

for.NET Aby uzyskać wskazówki dotyczące tworzenia nowoczesnej, niezawodnej, wydajnej, ekonomicznej i skalowalnej aplikacji ASP.NET Core, zapoznaj się ze wskazówkami dotyczącymi tworzenia nowoczesnej, niezawodnej, wydajnej i skalowalnej aplikacji platformy ASP.NET Core, od podstaw lub refaktoryzacji istniejącej aplikacji.

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 Connect 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: