Delen via


Zelfstudie: Een web-API op basis van een controller maken met ASP.NET Core

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Door Tim Deschryver en Rick Anderson

In deze zelfstudie leert u de basisbeginselen van het bouwen van een web-API op basis van een controller die gebruikmaakt van een database. Een andere benadering voor het maken van API's in ASP.NET Core is het maken van minimale API's. Zie het overzicht van API'svoor hulp bij het kiezen tussen minimale API's en api's op basis van een controller. Zie Zelfstudie: Een minimale API maken met ASP.NET Corevoor een zelfstudie over het maken van een minimale API.

Overzicht

In deze tutorial maak je de volgende API aan:

API Beschrijving Verzoekinhoud Hoofdtekst van antwoord
GET /api/todoitems Alle to-do items ophalen Geen Matrix van to-do items
GET /api/todoitems/{id} Een item ophalen met ID Geen Takenitem
POST /api/todoitems Een nieuw item toevoegen Actiepunt Actiepunt
PUT /api/todoitems/{id} Een bestaand item bijwerken Takenitem Geen
DELETE /api/todoitems/{id}     Een item verwijderen Geen Geen

In het volgende diagram ziet u het ontwerp van de app.

De client wordt vertegenwoordigd door een vak aan de linkerkant. Het verzendt een aanvraag en ontvangt een antwoord van de toepassing, een vak aan de rechterkant. In het toepassingsvak vertegenwoordigen drie vakken de controller, het model en de gegevenstoegangslaag. De aanvraag wordt geleverd in de controller van de toepassing en lees-/schrijfbewerkingen worden uitgevoerd tussen de controller en de gegevenstoegangslaag. Het model wordt geserialiseerd en geretourneerd naar de client in het antwoord.

Voorwaarden

Een web-API-project maken

  • Selecteer in het menu BestandNieuw>Project.
  • Voer Web-API- in het zoekvak in.
  • Selecteer de sjabloon ASP.NET Core Web API en selecteer Volgende.
  • Geef in het dialoogvenster Je nieuwe project configurerende naam van het project TodoApi en selecteer Volgende.
  • In het dialoogvenster Aanvullende informatie:
    • Controleer of de Framework- is .NET 9.0 (Standard Term Support).
    • Controleer of het selectievakje voor OpenAPI-ondersteuning inschakelen is ingeschakeld.
    • Controleer of het selectievakje voor Controllers gebruiken is aangevinkt (schakel het uit om minimale API's te gebruiken).
    • Selecteer Aanmaken.

Een NuGet-pakket toevoegen

Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.

  • Selecteer in het menu ToolsNuGet Package Manager > NuGet-pakketten beheren voor Solution.
  • Selecteer het tabblad Bladeren.
  • Voer Microsoft.EntityFrameworkCore.InMemory- in het zoekvak in en selecteer vervolgens Microsoft.EntityFrameworkCore.InMemory.
  • Selecteer het selectievakje Project in het rechterdeelvenster en selecteer vervolgens installeren.

Notitie

Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptiewerkstroom (NuGet-documentatie)voor hulp bij het toevoegen van pakketten aan .NET-apps. Bevestig de juiste pakketversies op NuGet.org.

Het project uitvoeren

De projectsjabloon maakt een WeatherForecast-API met ondersteuning voor OpenAPI-.

Druk op Ctrl+F5 om uit te voeren zonder het foutopsporingsprogramma.

Visual Studio geeft het volgende dialoogvenster weer wanneer een project nog niet is geconfigureerd voor het gebruik van SSL:

Dit project is geconfigureerd voor het gebruik van SSL. Als u SSL-waarschuwingen in de browser wilt voorkomen, kunt u ervoor kiezen om het zelfondertekende certificaat te vertrouwen dat IIS Express heeft gegenereerd. Wilt u het IIS Express SSL-certificaat vertrouwen?

Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.

Het volgende dialoogvenster wordt weergegeven:

beveiligingswaarschuwingsdialoogvenster

Selecteer Ja als u akkoord gaat met het vertrouwen van het ontwikkelingscertificaat.

Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfoutvoor meer informatie over het vertrouwen van de Firefox-browser.

Visual Studio start een terminalvenster en geeft de URL van de actieve app weer. De API wordt gehost op https://localhost:<port>, waarbij <port> een willekeurig gekozen poortnummer is dat is ingesteld bij het maken van het project.

...
info: Microsoft.Hosting.Lifetime[14]
   Now listening on: https://localhost:7260
info: Microsoft.Hosting.Lifetime[14]
   Now listening on: http://localhost:7261
info: Microsoft.Hosting.Lifetime[0]
   Application started. Press Ctrl+C to shut down.
...

Ctrl+klikt u op de HTTPS-URL in de uitvoer om de web-app in een browser te testen. Er is geen eindpunt op https://localhost:<port>, dus de browser retourneert HTTP 404 Niet gevonden.

Voeg /weatherforecast toe aan de URL om de WeatherForecast-API te testen. In de browser wordt JSON weergegeven die vergelijkbaar is met het volgende voorbeeld:

[
    {
        "date": "2025-07-16",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2025-07-17",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2025-07-18",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2025-07-19",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2025-07-20",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Het project testen

In deze zelfstudie worden Endpoints Explorer en .http-bestanden gebruikt om de API te testen.

Een modelklasse toevoegen

Een model is een set klassen die de gegevens vertegenwoordigen die door de app worden beheerd. Het model voor deze app is de TodoItem klasse.

  • Klik in Solution Explorer-met de rechtermuisknop op het project. Selecteer Nieuwe map toevoegen>. Geef de map een naam Models.
  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoItem en selecteer toevoegen.
  • Vervang de sjablooncode door het volgende:
namespace TodoApi.Models;

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

De eigenschap Id fungeert als de unieke sleutel in een relationele database.

Modelklassen kunnen overal in het project worden gebruikt, maar de map Models wordt standaard gebruikt.

Een databasecontext toevoegen

De databasecontext is de belangrijkste klasse die de functionaliteit van Entity Framework coördineert voor een gegevensmodel. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.

  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoContext en klik op Toevoegen.

  • Voer de volgende code in:

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

De databasecontext registreren

In ASP.NET Core moeten services zoals de DB-context worden geregistreerd bij de afhankelijkheidsinjectie (DI) container. De container biedt de service aan controllers.

Werk Program.cs bij met de volgende gemarkeerde code:

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

De voorgaande code:

  • Voegt using richtlijnen toe.
  • Voegt de databasecontext toe aan de DI-container.
  • Hiermee geeft u op dat de databasecontext een in-memory database gebruikt.

Genereer een controller

  • Klik met de rechtermuisknop op de map Controllers.

  • Selecteer >New Scaffolded Itemtoevoegen.

  • Selecteer API-controller met acties, met behulp van Entity Framework-en selecteer vervolgens toevoegen.

  • In het dialoogvenster "API-controller met acties toevoegen", met behulp van Entity Framework:

    • Selecteer TodoItem (TodoApi.Models) in de modelklasse.
    • Selecteer TodoContext (TodoApi.Models) in de gegevens contextklasse .
    • Selecteer toevoegen.

    Als de scaffolding mislukt, selecteert u Toevoegen om de scaffolding een tweede keer uit te voeren.

Met deze stap worden de Microsoft.VisualStudio.Web.CodeGeneration.Design- en Microsoft.EntityFrameworkCore.Tools NuGet-pakketten aan het project toegevoegd. Deze pakketten zijn vereist voor steigerbouw.

De gegenereerde code:

  • Markeert de klasse met het kenmerk [ApiController]. Dit kenmerk geeft aan dat de controller reageert op web-API-aanvragen. Zie Web-API's maken met ASP.NET Corevoor informatie over specifiek gedrag dat het kenmerk inschakelt.
  • Maakt gebruik van DI om de databasecontext (TodoContext) in de controller te injecteren. De databasecontext wordt gebruikt in elk van de CRUD methoden in de controller.

De ASP.NET Core-sjablonen voor:

  • Controllers met weergaven bevatten [action] in de routesjabloon.
  • API-controllers bevatten geen [action] in de routesjabloon.

Wanneer het [action] token zich niet in de routesjabloon bevindt, wordt de actie naam (methodenaam) niet opgenomen in het eindpunt. Dat wil gezegd: de naam van de gekoppelde methode van de actie wordt niet gebruikt in de overeenkomende route.

De methode voor het aanmaken van PostTodoItem bijwerken

Werk de retourinstructie in de PostTodoItem bij om de nameof operator te gebruiken.

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

De voorgaande code is een HTTP POST methode, zoals aangegeven door het kenmerk [HttpPost]. Met de methode wordt de waarde van de TodoItem opgehaald uit de hoofdtekst van de HTTP-aanvraag.

Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

De methode CreatedAtAction:

  • Retourneert een HTTP 201-statuscode als dit lukt. HTTP 201 is het standaardantwoord voor een HTTP POST methode waarmee een nieuwe resource op de server wordt gemaakt.
  • Hiermee voegt u een location header toe aan het antwoord. De Location-header geeft de URI- van het zojuist gemaakte to-do-item op. Zie 10.2.2 201 Gemaaktvoor meer informatie.
  • Verwijst naar de GetTodoItem actie om de URI van de Location header te maken. Het trefwoord C# nameof wordt gebruikt om te voorkomen dat de actienaam in de CreatedAtAction aanroep hard wordt gecodeerd.

PostTodoItem testen

  • Selecteer Weergave>Andere vensters>Endpoints Explorer.

  • Klik met de rechtermuisknop op het eindpunt POST en selecteer Aanvraag genereren.

    contextmenu van Endpoints Explorer waarin het menu-item Aanvraag genereren is gemarkeerd.

    Er wordt een nieuw bestand gemaakt in de projectmap met de naam TodoApi.http, met inhoud die vergelijkbaar is met het volgende voorbeeld:

    @TodoApi_HostAddress = https://localhost:49738
    
    POST {{TodoApi_HostAddress}}/api/todoitems
    Content-Type: application/json
    
    {
      //TodoItem
    }
    
    ###
    
    • Met de eerste regel maakt u een variabele die wordt gebruikt voor alle eindpunten.
    • De volgende regel definieert een POST-aanvraag.
    • De regels na de POST-aanvraagregel definiëren de headers en een tijdelijke aanduiding voor de aanvraagbody.
    • De regel met de drievoudige hashtag (###) is een scheidingsteken voor aanvragen: wat erna komt, is voor een andere aanvraag.
  • De POST-aanvraag verwacht een TodoItem. Om de todo te definiëren, vervangt u de //TodoItem opmerking door de volgende JSON:

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

    Het todoApi.http-bestand moet er nu uitzien zoals in het volgende voorbeeld, maar met uw poortnummer:

    @TodoApi_HostAddress = https://localhost:7260
    
    Post {{TodoApi_HostAddress}}/api/todoitems
    Content-Type: application/json
    
    {
      "name": "walk dog",
      "isComplete": true
    }
    
    ###
    
  • Voer de app uit.

  • Selecteer de koppeling Aanvraag verzenden boven de POST aanvraagregel.

    .http-bestandvenster met run link gemarkeerd.

    De POST-aanvraag wordt verzonden naar de app en het antwoord wordt weergegeven in het deelvenster Antwoord.

    .http-bestandvenster met reactie van de POST-aanvraag.

De URI van de locatieheader testen

Test de app door de GET-eindpunten aan te roepen vanuit een browser of met behulp van Endpoints Explorer. De volgende stappen zijn bedoeld voor Endpoints Explorer.

  • Klik in Endpoints Explorermet de rechtermuisknop op het eerste GET--eindpunt en selecteer Aanvraag genereren.

    De volgende inhoud wordt toegevoegd aan het TodoApi.http-bestand:

    GET {{TodoApi_HostAddress}}/api/todoitems
    
    ###
    
  • Selecteer de koppeling Aanvraag verzenden boven de nieuwe GET aanvraagregel.

    De GET-aanvraag wordt verzonden naar de app en het antwoord wordt weergegeven in het deelvenster Antwoord.

  • De hoofdtekst van het antwoord is vergelijkbaar met de volgende JSON:

    [
      {
        "id": 1,
        "name": "walk dog",
        "isComplete": true
      }
    ]
    
  • Klik in Endpoints Explorermet de rechtermuisknop op het eindpunt /api/todoitems/{id}GET en selecteer Aanvraag genereren. De volgende inhoud wordt toegevoegd aan het TodoApi.http-bestand:

    @id=0
    GET {{TodoApi_HostAddress}}/api/todoitems/{{id}}
    
    ###
    
  • Wijs {@id} toe aan 1 (in plaats van 0).

  • Selecteer de aanvraag verzenden koppeling die zich boven de nieuwe GET-aanvraagregel bevindt.

    De GET-aanvraag wordt verzonden naar de app en het antwoord wordt weergegeven in het deelvenster Antwoord.

  • De hoofdtekst van het antwoord is vergelijkbaar met de volgende JSON:

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

De GET-methoden onderzoeken

Er worden twee GET-eindpunten geïmplementeerd:

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

In de vorige sectie is een voorbeeld van de /api/todoitems/{id} route getoond.

Volg de POST instructies om nog een to-do item toe te voegen en test vervolgens de /api/todoitems route met Swagger.

Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. Als er geen gegevens worden geretourneerd, POST gegevens naar de app.

Routering en URL-paden

Het kenmerk [HttpGet] geeft een methode aan die reageert op een HTTP GET aanvraag. Het URL-pad voor elke methode wordt als volgt samengesteld:

  • Begin met de sjabloontekenreeks in het kenmerk Route van de controller:

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Vervang [controller] door de naam van de controller. Dit is de naam van de controllerklasse minus het achtervoegsel 'Controller'. Voor dit voorbeeld is de naam van de controllerklasse TodoItemsController, dus de naam van de controller is 'TodoItems'. ASP.NET Core routing is niet hoofdlettergevoelig.

  • Als het kenmerk [HttpGet] een routesjabloon heeft (bijvoorbeeld [HttpGet("products")]), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

In de volgende GetTodoItem-methode is "{id}" een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem wordt aangeroepen, wordt de waarde van "{id}" in de URL verstrekt aan de methode in de parameter 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;
}

Retourwaarden

Het retourtype van de GetTodoItems- en GetTodoItem methoden is ActionResult<T-> type. ASP.NET Core het object automatisch serialiseert naar JSON- en schrijft de JSON naar de hoofdtekst van het antwoordbericht. De antwoordcode voor dit retourtype is 200 OK, ervan uitgaande dat er geen onverwerkte uitzonderingen zijn. Niet-verwerkte uitzonderingen worden omgezet in 5xx-fouten.

ActionResult retourtypen kunnen een breed scala aan HTTP-statuscodes vertegenwoordigen. GetTodoItem kan bijvoorbeeld twee verschillende statuswaarden retourneren:

  • Als er geen item overeenkomt met de aangevraagde id, retourneert de methode een 404-statusNotFound foutcode.
  • Anders retourneert de methode 200 met een JSON-antwoordtekst. Het retourneren van item resulteert in een HTTP 200 antwoord.

De methode PutTodoItem

Bekijk de PutTodoItem methode:

[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 is vergelijkbaar met PostTodoItem, met uitzondering van HTTP PUT. Het antwoord is 204 (geen inhoud). Volgens de HTTP-specificatie vereist een PUT aanvraag dat de client de volledige bijgewerkte entiteit verzendt, niet alleen de wijzigingen. Gebruik HTTP PATCH-om gedeeltelijke updates te ondersteunen.

De methode PutTodoItem testen

In dit voorbeeld wordt een in-memory database gebruikt die telkens wanneer de app wordt gestart, moet worden geïnitialiseerd. Er moet een item in de database staan voordat u een PUT-aanroep uitvoert. Roep GET aan om ervoor te zorgen dat er een item in de database staat voordat u een PUT-aanroep doet.

Gebruik de methode PUT om de TodoItem met id = 1 bij te werken en de naam ervan in te stellen op "feed fish". Let op: het antwoord is HTTP 204 No Content.

  • Klik in Endpoints Explorermet de rechtermuisknop op het PUT-eindpunt en selecteer Aanvraag genereren.

    De volgende inhoud wordt toegevoegd aan het TodoApi.http-bestand:

    PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}}
    Content-Type: application/json
    
    {
      //TodoItem
    }
    
    ###
    
  • Vervang {{id}} in de PUT-aanvraagregel door 1.

  • Vervang de tijdelijke aanduiding //TodoItem door de volgende regels:

    PUT {{TodoApi_HostAddress}}/api/todoitems/1
    Content-Type: application/json
    
    {
      "id": 1,
      "name": "feed fish",
      "isComplete": false
    }
    
  • Selecteer de koppeling Aanvraag verzenden boven de nieuwe PUT-aanvraagregel.

    De PUT-aanvraag wordt verzonden naar de app en het antwoord wordt weergegeven in het deelvenster Antwoord. De hoofdtekst van het antwoord is leeg en de statuscode is 204.

De methode DeleteTodoItem

Bekijk de DeleteTodoItem methode:

[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();
}

De methode DeleteTodoItem testen

Gebruik de methode DELETE om de TodoItem met id = 1 te verwijderen. Let op: het antwoord is HTTP 204 No Content.

  • Klik in Endpoints Explorermet de rechtermuisknop op het eindpunt DELETE en selecteer Aanvraag genereren.

    Er wordt een DELETE-aanvraag toegevoegd aan TodoApi.http.

  • Vervang {{id}} in de regel van de DELETE-aanvraag door 1. De DELETE-aanvraag moet eruitzien als in het volgende voorbeeld:

    DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}}
    
    ###
    
  • Selecteer de koppeling Aanvraag verzenden voor de DELETE-aanvraag.

    De DELETE-aanvraag wordt verzonden naar de app en het antwoord wordt weergegeven in het deelvenster Antwoord. De hoofdtekst van het antwoord is leeg en de statuscode is 204.

Testen met andere hulpprogramma's

Er zijn veel andere hulpprogramma's die kunnen worden gebruikt om web-API's te testen, bijvoorbeeld:

Zie voor meer informatie:

Overmatig posten voorkomen

Op dit moment wordt in de voorbeeld-app het hele TodoItem-object weergegeven. Productie-apps beperken doorgaans de gegevens die worden ingevoerd en geretourneerd met behulp van een subset van het model. Er zijn meerdere redenen achter dit, en beveiliging is een belangrijke. De subset van een model wordt meestal aangeduid als een DTO (Data Transfer Object), invoermodel of weergavemodel. DTO- wordt in deze handleiding gebruikt.

Een DTO kan worden gebruikt voor het volgende:

  • Voorkom overposten.
  • Eigenschappen verbergen die klanten niet zouden moeten zien.
  • Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
  • Platte objectgrafieken die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.

Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem klasse bij om een geheim veld op te nemen:

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

Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.

Controleer of u het geheime veld kunt posten en ophalen.

Maak een DTO-model in een bestand Models/TodoItemsDTO.cs:

namespace TodoApi.Models;

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

Werk de TodoItemsController bij om TodoItemDTOte gebruiken:

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

Controleer of u het geheime veld niet kunt posten of ophalen.

De web-API aanroepen met JavaScript

Zie zelfstudie: Een ASP.NET Core-web-API aanroepen met JavaScript-.

Web-API-videoserie

Zie Video: Beginnersserie van Web-API's.

Patronen voor bedrijfsweb-apps

Zie Enterprise-web-app-patronenvoor hulp bij het maken van een betrouwbare, veilige, uitvoerbare, testbare en schaalbare ASP.NET Core-app. Er is een volledige voorbeeldweb-app van productiekwaliteit beschikbaar waarmee de patronen worden geïmplementeerd.

Verificatieondersteuning toevoegen aan een web-API

ASP.NET Core Identity voegt de aanmeldingsfunctionaliteit van de gebruikersinterface (UI) toe aan ASP.NET Core-web-apps. Gebruik een van de volgende manieren om web-API's en SPA's te beveiligen:

Duende Identity Server is een OpenID Connect- en OAuth 2.0-framework voor ASP.NET Core. Duende Identity Server maakt de volgende beveiligingsfuncties mogelijk:

  • Verificatie als een service (AaaS)
  • Eenmalige aanmelding/uit (SSO) voor meerdere toepassingstypen
  • Toegangsbeheer voor API's
  • Federatie-gateway

Belangrijk

Duende Software moet u mogelijk een licentiekosten betalen voor productiegebruik van Duende Identity Server. Zie Migreren van ASP.NET Core 5.0 naar 6.0voor meer informatie.

Zie de Duende Identity Server-documentatie (Duende Software-website)voor meer informatie.

Publiceren naar Azure

Zie Quickstart: Een ASP.NET-web-app implementerenvoor meer informatie over het implementeren in Azure.

Aanvullende informatiebronnen

Bekijk of download de voorbeeldcode voor deze tutorial. Zie hoe u kunt downloaden.

Zie de volgende bronnen voor meer informatie:

In deze zelfstudie leert u de basisbeginselen van het bouwen van een web-API op basis van een controller die gebruikmaakt van een database. Een andere benadering voor het maken van API's in ASP.NET Core is het maken van minimale API's. Zie het overzicht van API'svoor hulp bij het kiezen tussen minimale API's en api's op basis van een controller. Zie Zelfstudie: Een minimale API maken met ASP.NET Corevoor een zelfstudie over het maken van een minimale API.

Overzicht

In deze tutorial maak je de volgende API aan:

API Beschrijving Verzoekinhoud Hoofdtekst van antwoord
GET /api/todoitems Alle to-do items ophalen Geen Matrix van to-do items
GET /api/todoitems/{id} Een item ophalen met ID Geen Takenitem
POST /api/todoitems Een nieuw item toevoegen Takenitem Takenitem
PUT /api/todoitems/{id} Een bestaand item bijwerken Takenitem Geen
DELETE /api/todoitems/{id}     Een item verwijderen Geen Geen

In het volgende diagram ziet u het ontwerp van de app.

De client wordt vertegenwoordigd door een vak aan de linkerkant. Het verzendt een aanvraag en ontvangt een antwoord van de toepassing, een vak aan de rechterkant. In het toepassingsvak vertegenwoordigen drie vakken de controller, het model en de gegevenstoegangslaag. De aanvraag wordt geleverd in de controller van de toepassing en lees-/schrijfbewerkingen worden uitgevoerd tussen de controller en de gegevenstoegangslaag. Het model wordt geserialiseerd en geretourneerd naar de client in het antwoord.

Voorwaarden

Een webproject maken

  • Selecteer in het menu BestandNieuw>Project.
  • Voer Web-API- in het zoekvak in.
  • Selecteer de sjabloon ASP.NET Core Web API en selecteer Volgende.
  • Geef in het dialoogvenster Je nieuwe project configurerende naam van het project TodoApi en selecteer Volgende.
  • In het dialoogvenster Aanvullende informatie:
    • Controleer of het Framework.NET 8.0 (Langetermijnondersteuning) is.
    • Controleer of het selectievakje voor Controllers gebruiken (schakel het selectievakje uit om minimale API's te gebruiken) is ingeschakeld.
    • Controleer of het selectievakje voor OpenAPI-ondersteuning inschakelen is ingeschakeld.
    • Selecteer Maken.

Een NuGet-pakket toevoegen

Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.

  • Selecteer in het menu ToolsNuGet Package Manager > NuGet-pakketten beheren voor Solution.
  • Selecteer het tabblad Bladeren.
  • Voer Microsoft.EntityFrameworkCore.InMemory- in het zoekvak in en selecteer vervolgens Microsoft.EntityFrameworkCore.InMemory.
  • Selecteer het selectievakje Project in het rechterdeelvenster en selecteer vervolgens installeren.

Notitie

Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptiewerkstroom (NuGet-documentatie)voor hulp bij het toevoegen van pakketten aan .NET-apps. Bevestig de juiste pakketversies op NuGet.org.

Het project testen

De projectsjabloon maakt een WeatherForecast API met ondersteuning voor Swagger.

Druk op Ctrl+F5 om uit te voeren zonder het foutopsporingsprogramma.

Visual Studio geeft het volgende dialoogvenster weer wanneer een project nog niet is geconfigureerd voor het gebruik van SSL:

Dit project is geconfigureerd voor het gebruik van SSL. Als u SSL-waarschuwingen in de browser wilt voorkomen, kunt u ervoor kiezen om het zelfondertekende certificaat te vertrouwen dat IIS Express heeft gegenereerd. Wilt u het IIS Express SSL-certificaat vertrouwen?

Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.

Het volgende dialoogvenster wordt weergegeven:

beveiligingswaarschuwingsdialoogvenster

Selecteer Ja als u akkoord gaat met het vertrouwen van het ontwikkelingscertificaat.

Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfoutvoor meer informatie over het vertrouwen van de Firefox-browser.

Visual Studio start de standaardbrowser en gaat naar https://localhost:<port>/swagger/index.html, waarbij <port> een willekeurig gekozen poortnummer is dat is ingesteld bij het maken van het project.

De Swagger-pagina /swagger/index.html wordt weergegeven. Selecteer Ophalen>Probeer het uit>Uitvoeren. Op de pagina wordt het volgende weergegeven:

  • De opdracht Curl om de WeatherForecast-API te testen.
  • De URL voor het testen van de WeatherForecast-API.
  • De antwoordcode, hoofdtekst en headers.
  • Een vervolgkeuzelijst met mediatypen en de voorbeeldwaarde en het schema.

Als de Swagger-pagina niet wordt weergegeven, raadpleegt u dit GitHub-probleem.

Swagger wordt gebruikt voor het genereren van nuttige documentatie en Help-pagina's voor web-API's. In deze zelfstudie wordt Swagger gebruikt om de app te testen. Zie ASP.NET Core-web-API-documentatie met Swagger/OpenAPI-voor meer informatie over Swagger.

Kopieer en plak de aanvraag-URL in de browser: https://localhost:<port>/weatherforecast

JSON die vergelijkbaar is met het volgende voorbeeld wordt geretourneerd:

[
    {
        "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"
    }
]

Een modelklasse toevoegen

Een model is een set klassen die de gegevens vertegenwoordigen die door de app worden beheerd. Het model voor deze app is de TodoItem klasse.

  • Klik in Solution Explorer-met de rechtermuisknop op het project. Selecteer Nieuwe map toevoegen>. Geef de map een naam Models.
  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoItem en selecteer toevoegen.
  • Vervang de sjablooncode door het volgende:
namespace TodoApi.Models;

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

De eigenschap Id fungeert als de unieke sleutel in een relationele database.

Modelklassen kunnen overal in het project worden gebruikt, maar de map Models wordt standaard gebruikt.

Een databasecontext toevoegen

De databasecontext is de belangrijkste klasse die de functionaliteit van Entity Framework coördineert voor een gegevensmodel. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.

  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoContext en klik op Toevoegen.
  • Voer de volgende code in:

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

De databasecontext registreren

In ASP.NET Core moeten services zoals de DB-context worden geregistreerd bij de afhankelijkheidsinjectie (DI) container. De container biedt de service aan controllers.

Werk Program.cs bij met de volgende gemarkeerde code:

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();

De voorgaande code:

  • Voegt using richtlijnen toe.
  • Voegt de databasecontext toe aan de DI-container.
  • Hiermee geeft u op dat de databasecontext een in-memory database gebruikt.

Genereer een controller

  • Klik met de rechtermuisknop op de map Controllers.

  • Selecteer >New Scaffolded Itemtoevoegen.

  • Selecteer API-controller met acties, met behulp van Entity Framework-en selecteer vervolgens toevoegen.

  • In het dialoogvenster "API-controller met acties toevoegen", met behulp van Entity Framework:

    • Selecteer TodoItem (TodoApi.Models) in de modelklasse.
    • Selecteer TodoContext (TodoApi.Models) in de gegevens contextklasse .
    • Selecteer toevoegen.

    Als de scaffolding-actie mislukt, selecteert u Toevoegen om de scaffolding een tweede keer te proberen.

De gegenereerde code:

  • Markeert de klasse met het kenmerk [ApiController]. Dit kenmerk geeft aan dat de controller reageert op web-API-aanvragen. Zie Web-API's maken met ASP.NET Corevoor informatie over specifiek gedrag dat het kenmerk inschakelt.
  • Maakt gebruik van DI om de databasecontext (TodoContext) in de controller te injecteren. De databasecontext wordt gebruikt in elk van de CRUD methoden in de controller.

De ASP.NET Core-sjablonen voor:

  • Controllers met weergaven bevatten [action] in het route-sjabloon.
  • API-controllers bevatten geen [action] in de routesjabloon.

Wanneer het [action] token zich niet in de routesjabloon bevindt, wordt de actie naam (methodenaam) niet opgenomen in het eindpunt. Dat wil gezegd: de naam van de gekoppelde methode van de actie wordt niet gebruikt in de overeenkomende route.

De methode voor het aanmaken van PostTodoItem bijwerken

Werk de returninstructie in de PostTodoItem bij om de nameof operator te gebruiken.

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

De voorgaande code is een HTTP POST methode, zoals aangegeven door het kenmerk [HttpPost]. Met de methode wordt de waarde van de TodoItem opgehaald uit de hoofdtekst van de HTTP-aanvraag.

Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

De methode CreatedAtAction:

  • Retourneert een HTTP 201-statuscode als dit lukt. HTTP 201 is het standaardantwoord voor een HTTP POST methode waarmee een nieuwe resource op de server wordt gemaakt.
  • Hiermee voegt u een location header toe aan het antwoord. De Location-header geeft de URI- van het zojuist gemaakte to-do-item op. Zie 10.2.2 201 Gemaaktvoor meer informatie.
  • Verwijst naar de GetTodoItem actie om de URI van de Location header te maken. Het trefwoord C# nameof wordt gebruikt om te voorkomen dat de actienaam in de CreatedAtAction aanroep hard wordt gecodeerd.

PostTodoItem testen

  • Druk op Ctrl+F5 om de app uit te voeren.

  • Selecteer in het browservenster van Swagger POST /api/TodoItemsen selecteer Probeer het.

  • Werk de JSON bij in het aanvraagbody invoervenster. Bijvoorbeeld

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • Selecteer Voer uit

    Swagger POST

De URI van de locatieheader testen

In de voorgaande POST toont de Swagger-gebruikersinterface de locatiekop onder Antwoordkoppen. Bijvoorbeeld location: https://localhost:7260/api/TodoItems/1. De locatieheader toont de URI voor de gemaakte resource.

De locatiekoptekst testen:

  • Selecteer in het browservenster van Swagger GET /api/TodoItems/{id}en selecteer Probeer het.

  • Voer 1 in het invoervak id in en selecteer omuit te voeren.

    Swagger GET

De GET-methoden onderzoeken

Er worden twee GET-eindpunten geïmplementeerd:

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

In de vorige sectie is een voorbeeld van de /api/todoitems/{id} route getoond.

Volg de POST instructies om nog een to-do item toe te voegen en test vervolgens de /api/todoitems route met Swagger.

Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. Als er geen gegevens worden geretourneerd, POST gegevens naar de app.

Routing en URL paden

Het kenmerk [HttpGet] geeft een methode aan die reageert op een HTTP GET aanvraag. Het URL-pad voor elke methode wordt als volgt samengesteld:

  • Begin met de sjabloontekenreeks in het kenmerk Route van de controller:

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Vervang [controller] door de naam van de controller. Dit is de naam van de controllerklasse minus het achtervoegsel 'Controller'. Voor dit voorbeeld is de naam van de controllerklasse TodoItemsController, dus de naam van de controller is 'TodoItems'. ASP.NET Core routing is niet hoofdlettergevoelig.

  • Als het kenmerk [HttpGet] een routesjabloon heeft (bijvoorbeeld [HttpGet("products")]), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

In de volgende GetTodoItem-methode is "{id}" een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem wordt aangeroepen, wordt de waarde van "{id}" in de URL verstrekt aan de methode in de parameter 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;
}

Retourwaarden

Het retourtype van de GetTodoItems- en GetTodoItem methoden is ActionResult<T-> type. ASP.NET Core het object automatisch serialiseert naar JSON- en schrijft de JSON naar de hoofdtekst van het antwoordbericht. De antwoordcode voor dit retourtype is 200 OK, ervan uitgaande dat er geen onverwerkte uitzonderingen zijn. Niet-verwerkte uitzonderingen worden omgezet in 5xx-fouten.

ActionResult retourtypen kunnen een breed scala aan HTTP-statuscodes vertegenwoordigen. GetTodoItem kan bijvoorbeeld twee verschillende statuswaarden retourneren:

  • Als er geen item overeenkomt met de aangevraagde id, retourneert de methode een 404-statusNotFound foutcode.
  • Anders retourneert de methode 200 met een JSON-antwoordtekst. Het retourneren van item resulteert in een HTTP 200 antwoord.

De methode PutTodoItem

Bekijk de PutTodoItem methode:

[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 is vergelijkbaar met PostTodoItem, met uitzondering van HTTP PUT. Het antwoord is 204 (geen inhoud). Volgens de HTTP-specificatie vereist een PUT aanvraag dat de client de volledige bijgewerkte entiteit verzendt, niet alleen de wijzigingen. Gebruik HTTP PATCH-om gedeeltelijke updates te ondersteunen.

De methode PutTodoItem testen

In dit voorbeeld wordt een in-memory database gebruikt die telkens wanneer de app wordt gestart, moet worden geïnitialiseerd. Er moet een item in de database staan voordat u een PUT-aanroep uitvoert. Roep GET aan om ervoor te zorgen dat er een item in de database staat voordat u een PUT-aanroep doet.

Gebruik de Swagger UI om de TodoItem met id = 1 bij te werken door de PUT-knop te gebruiken en stel de naam in op "feed fish". Let op: het antwoord is HTTP 204 No Content.

De methode DeleteTodoItem

Bekijk de DeleteTodoItem methode:

[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();
}

De methode DeleteTodoItem testen

Gebruik de Swagger-gebruikersinterface om de TodoItem met Id = 1 te verwijderen. Let op: het antwoord is HTTP 204 No Content.

Testen met andere hulpprogramma's

Er zijn veel andere hulpprogramma's die kunnen worden gebruikt om web-API's te testen, bijvoorbeeld:

Zie voor meer informatie:

Overmatig posten voorkomen

Op dit moment wordt in de voorbeeld-app het hele TodoItem-object weergegeven. Productie-apps beperken doorgaans de gegevens die worden ingevoerd en geretourneerd met behulp van een subset van het model. Er zijn meerdere redenen achter dit, en beveiliging is een belangrijke. De subset van een model wordt meestal aangeduid als een DTO (Data Transfer Object), invoermodel of weergavemodel. DTO- wordt in deze handleiding gebruikt.

Een DTO kan worden gebruikt voor het volgende:

  • Voorkom overposten.
  • Eigenschappen verbergen die klanten niet zouden moeten zien.
  • Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
  • Platte objectgrafieken die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.

Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem klasse bij om een geheim veld op te nemen:

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

Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.

Controleer of u het geheime veld kunt posten en ophalen.

Een DTO-model maken:

namespace TodoApi.Models;

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

Werk de TodoItemsController bij om TodoItemDTOte gebruiken:

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

Controleer of u het geheime veld niet kunt posten of ophalen.

De web-API aanroepen met JavaScript

Zie zelfstudie: Een ASP.NET Core-web-API aanroepen met JavaScript-.

Web-API-videoserie

Zie Video: Beginnersserie van Web-API's.

Patronen voor bedrijfsweb-apps

Zie Enterprise-web-app-patronenvoor hulp bij het maken van een betrouwbare, veilige, uitvoerbare, testbare en schaalbare ASP.NET Core-app. Er is een volledige voorbeeldweb-app van productiekwaliteit beschikbaar waarmee de patronen worden geïmplementeerd.

Verificatieondersteuning toevoegen aan een web-API

ASP.NET Core Identity voegt de aanmeldingsfunctionaliteit van de gebruikersinterface (UI) toe aan ASP.NET Core-web-apps. Gebruik een van de volgende manieren om web-API's en SPA's te beveiligen:

Duende Identity Server is een OpenID Connect- en OAuth 2.0-framework voor ASP.NET Core. Duende Identity Server maakt de volgende beveiligingsfuncties mogelijk:

  • Verificatie als een service (AaaS)
  • Eenmalige aanmelding/uit (SSO) voor meerdere toepassingstypen
  • Toegangsbeheer voor API's
  • Federatie-gateway

Belangrijk

Duende Software moet u mogelijk een licentiekosten betalen voor productiegebruik van Duende Identity Server. Zie Migreren van ASP.NET Core 5.0 naar 6.0voor meer informatie.

Zie de Duende Identity Server-documentatie (Duende Software-website)voor meer informatie.

Publiceren naar Azure

Zie Quickstart: Een ASP.NET-web-app implementerenvoor meer informatie over het implementeren in Azure.

Aanvullende informatiebronnen

Bekijk of download de voorbeeldcode voor deze tutorial. Zie hoe te downloaden.

Zie de volgende bronnen voor meer informatie:

In deze zelfstudie leert u de basisbeginselen van het bouwen van een web-API op basis van een controller die gebruikmaakt van een database. Een andere benadering voor het maken van API's in ASP.NET Core is het maken van minimale API's. Zie het overzicht van API'svoor hulp bij het kiezen tussen minimale API's en api's op basis van een controller. Zie Zelfstudie: Een minimale API maken met ASP.NET Corevoor een zelfstudie over het maken van een minimale API.

Overzicht

In deze tutorial maak je de volgende API aan:

API Beschrijving Verzoekinhoud Hoofdtekst van antwoord
GET /api/todoitems Alle to-do-items ophalen Geen Lijst van te-doen items
GET /api/todoitems/{id} Een item ophalen met ID Geen Actiepunt
POST /api/todoitems Een nieuw item toevoegen Actiepunt Actiepunt
PUT /api/todoitems/{id} Een bestaand item bijwerken Takenitem Geen
DELETE /api/todoitems/{id}     Een item verwijderen Geen Geen

In het volgende diagram ziet u het ontwerp van de app.

De client wordt vertegenwoordigd door een vak aan de linkerkant. Het verzendt een aanvraag en ontvangt een antwoord van de toepassing, een vak aan de rechterkant. In het toepassingsvak vertegenwoordigen drie vakken de controller, het model en de gegevenstoegangslaag. De aanvraag wordt geleverd in de controller van de toepassing en lees-/schrijfbewerkingen worden uitgevoerd tussen de controller en de gegevenstoegangslaag. Het model wordt geserialiseerd en geretourneerd naar de client in het antwoord.

Voorwaarden

Een webproject maken

  • Selecteer in het menu BestandNieuw>Project.
  • Voer Web-API- in het zoekvak in.
  • Selecteer de sjabloon ASP.NET Core Web API en selecteer Volgende.
  • Geef in het dialoogvenster Je nieuwe project configurerende naam van het project TodoApi en selecteer Volgende.
  • In het dialoogvenster Aanvullende informatie:
    • Controleer of het Framework.NET 8.0 (Langetermijnondersteuning) is.
    • Controleer of het selectievakje voor Controllers gebruiken (schakel het selectievakje uit om minimale API's te gebruiken) is ingeschakeld.
    • Controleer of het selectievakje voor OpenAPI-ondersteuning inschakelen is ingeschakeld.
    • Selecteer Create.

Een NuGet-pakket toevoegen

Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.

  • Selecteer in het menu ToolsNuGet Package Manager > NuGet-pakketten beheren voor Solution.
  • Selecteer het tabblad Bladeren.
  • Voer Microsoft.EntityFrameworkCore.InMemory- in het zoekvak in en selecteer vervolgens Microsoft.EntityFrameworkCore.InMemory.
  • Selecteer het selectievakje Project in het rechterdeelvenster en selecteer vervolgens installeren.

Notitie

Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptiewerkstroom (NuGet-documentatie)voor hulp bij het toevoegen van pakketten aan .NET-apps. Bevestig de juiste pakketversies op NuGet.org.

Het project testen

De projectsjabloon maakt een WeatherForecast API met ondersteuning voor Swagger.

Druk op Ctrl+F5 om uit te voeren zonder het foutopsporingsprogramma.

Visual Studio geeft het volgende dialoogvenster weer wanneer een project nog niet is geconfigureerd voor het gebruik van SSL:

Dit project is geconfigureerd voor het gebruik van SSL. Als u SSL-waarschuwingen in de browser wilt voorkomen, kunt u ervoor kiezen om het zelfondertekende certificaat te vertrouwen dat IIS Express heeft gegenereerd. Wilt u het IIS Express SSL-certificaat vertrouwen?

Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.

Het volgende dialoogvenster wordt weergegeven:

beveiligingswaarschuwingsdialoogvenster

Selecteer Ja als u akkoord gaat met het vertrouwen van het ontwikkelingscertificaat.

Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfoutvoor meer informatie over het vertrouwen van de Firefox-browser.

Visual Studio start de standaardbrowser en gaat naar https://localhost:<port>/swagger/index.html, waarbij <port> een willekeurig gekozen poortnummer is dat is ingesteld bij het maken van het project.

De Swagger-pagina /swagger/index.html wordt weergegeven. Selecteer Ophalen>Probeer het uit>Uitvoeren. Op de pagina wordt het volgende weergegeven:

  • De opdracht Curl om de WeatherForecast-API te testen.
  • De URL voor het testen van de WeatherForecast-API.
  • De antwoordcode, hoofdtekst en headers.
  • Een vervolgkeuzelijst met mediatypen en de voorbeeldwaarde en het schema.

Als de Swagger-pagina niet wordt weergegeven, raadpleegt u dit GitHub-probleem.

Swagger wordt gebruikt voor het genereren van nuttige documentatie en Help-pagina's voor web-API's. In deze zelfstudie wordt Swagger gebruikt om de app te testen. Zie ASP.NET Core-web-API-documentatie met Swagger/OpenAPI-voor meer informatie over Swagger.

Kopieer en plak de aanvraag-URL in de browser: https://localhost:<port>/weatherforecast

JSON die vergelijkbaar is met het volgende voorbeeld wordt geretourneerd:

[
    {
        "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"
    }
]

Een modelklasse toevoegen

Een model is een set klassen die de gegevens vertegenwoordigen die door de app worden beheerd. Het model voor deze app is de TodoItem klasse.

  • Klik in Solution Explorer-met de rechtermuisknop op het project. Selecteer Nieuwe map toevoegen>. Geef de map een naam Models.
  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoItem en selecteer toevoegen.
  • Vervang de sjablooncode door het volgende:
namespace TodoApi.Models;

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

De eigenschap Id fungeert als de unieke sleutel in een relationele database.

Modelklassen kunnen overal in het project worden gebruikt, maar de map Models wordt standaard gebruikt.

Een databasecontext toevoegen

De databasecontext is de belangrijkste klasse die de functionaliteit van Entity Framework coördineert voor een gegevensmodel. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.

  • Klik met de rechtermuisknop op de map Models en selecteer >Classtoevoegen. Noem de klasse TodoContext en klik op Toevoegen.
  • Voer de volgende code in:

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

De databasecontext registreren

In ASP.NET Core moeten services zoals de DB-context worden geregistreerd bij de afhankelijkheidsinjectie (DI) container. De container biedt de service aan controllers.

Werk Program.cs bij met de volgende gemarkeerde code:

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();

De voorgaande code:

  • Voegt using richtlijnen toe.
  • Voegt de databasecontext toe aan de DI-container.
  • Hiermee geeft u op dat de databasecontext een in-memory database gebruikt.

Genereer een controller

  • Klik met de rechtermuisknop op de map Controllers.

  • Selecteer >New Scaffolded Itemtoevoegen.

  • Selecteer API-controller met acties, met behulp van Entity Framework-en selecteer vervolgens toevoegen.

  • In het dialoogvenster "API-controller met acties toevoegen", met behulp van Entity Framework:

    • Selecteer TodoItem (TodoApi.Models) in de modelklasse.
    • Selecteer TodoContext (TodoApi.Models) in de gegevens contextklasse .
    • Selecteer toevoegen.

    Als de scaffolding mislukt, selecteert u Toevoegen om de scaffolding een tweede keer uit te voeren.

De gegenereerde code:

  • Markeert de klasse met het kenmerk [ApiController]. Dit kenmerk geeft aan dat de controller reageert op web-API-aanvragen. Zie Web-API's maken met ASP.NET Corevoor informatie over specifiek gedrag dat het kenmerk inschakelt.
  • Maakt gebruik van DI om de databasecontext (TodoContext) in de controller te injecteren. De databasecontext wordt gebruikt in elk van de CRUD methoden in de controller.

De ASP.NET Core-sjablonen voor:

  • Controllers met weergaven bevatten [action] in de routesjabloon.
  • API-controllers bevatten geen [action] in de routesjabloon.

Wanneer het [action] token zich niet in de routesjabloon bevindt, wordt de actie naam (methodenaam) niet opgenomen in het eindpunt. Dat wil gezegd: de naam van de gekoppelde methode van de actie wordt niet gebruikt in de overeenkomende route.

De methode voor het aanmaken van PostTodoItem bijwerken

Werk de retourinstructie in de PostTodoItem bij om de nameof operator te gebruiken.

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

De voorgaande code is een HTTP POST methode, zoals aangegeven door het kenmerk [HttpPost]. Met de methode wordt de waarde van de TodoItem opgehaald uit de hoofdtekst van de HTTP-aanvraag.

Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

De methode CreatedAtAction:

  • Retourneert een HTTP 201-statuscode als dit lukt. HTTP 201 is het standaardantwoord voor een HTTP POST methode waarmee een nieuwe resource op de server wordt gemaakt.
  • Hiermee voegt u een location header toe aan het antwoord. De Location-header geeft de URI- van het zojuist gemaakte to-do-item op. Zie 10.2.2 201 Gemaaktvoor meer informatie.
  • Verwijst naar de GetTodoItem actie om de URI van de Location header te maken. Het trefwoord C# nameof wordt gebruikt om te voorkomen dat de actienaam in de CreatedAtAction aanroep hard wordt gecodeerd.

PostTodoItem testen

  • Druk op Ctrl+F5 om de app uit te voeren.

  • Selecteer in het browservenster van Swagger POST /api/TodoItemsen selecteer Probeer het.

  • Werk de JSON bij in het aanvraagbody invoervenster. Bijvoorbeeld

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • Selecteer Voer uit

    Swagger POST

De URI van de locatieheader testen

In de voorgaande POST toont de Swagger-gebruikersinterface de locatiekop onder Antwoordkoppen. Bijvoorbeeld location: https://localhost:7260/api/TodoItems/1. De locatieheader toont de URI voor de gemaakte resource.

De locatiekoptekst testen:

  • Selecteer in het browservenster van Swagger GET /api/TodoItems/{id}en selecteer Probeer het.

  • Voer 1 in het invoervak id in en selecteer omuit te voeren.

    Swagger GET

De GET-methoden onderzoeken

Er worden twee GET-eindpunten geïmplementeerd:

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

In de vorige sectie is een voorbeeld van de /api/todoitems/{id} route getoond.

Volg de POST instructies om nog een to-do item toe te voegen en test vervolgens de /api/todoitems route met Swagger.

Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. Als er geen gegevens worden geretourneerd, POST gegevens naar de app.

Routeren en URL-paden

Het kenmerk [HttpGet] geeft een methode aan die reageert op een HTTP GET aanvraag. Het URL-pad voor elke methode wordt als volgt samengesteld:

  • Begin met de sjabloontekenreeks in het kenmerk Route van de controller:

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • Vervang [controller] door de naam van de controller. Dit is de naam van de controllerklasse minus het achtervoegsel 'Controller'. Voor dit voorbeeld is de naam van de controllerklasse TodoItemsController, dus de naam van de controller is 'TodoItems'. ASP.NET Core routing is niet hoofdlettergevoelig.

  • Als het kenmerk [HttpGet] een routesjabloon heeft (bijvoorbeeld [HttpGet("products")]), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie kenmerkroutering met http[werkwoord]-kenmerkenvoor meer informatie.

In de volgende GetTodoItem-methode is "{id}" een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem wordt aangeroepen, wordt de waarde van "{id}" in de URL verstrekt aan de methode in de parameter 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;
}

Retourwaarden

Het retourtype van de GetTodoItems- en GetTodoItem methoden is ActionResult<T-> type. ASP.NET Core het object automatisch serialiseert naar JSON- en schrijft de JSON naar de hoofdtekst van het antwoordbericht. De antwoordcode voor dit retourtype is 200 OK, ervan uitgaande dat er geen onverwerkte uitzonderingen zijn. Niet-verwerkte uitzonderingen worden omgezet in 5xx-fouten.

ActionResult retourtypen kunnen een breed scala aan HTTP-statuscodes vertegenwoordigen. GetTodoItem kan bijvoorbeeld twee verschillende statuswaarden retourneren:

  • Als er geen item overeenkomt met de aangevraagde id, retourneert de methode een 404-statusNotFound foutcode.
  • Anders retourneert de methode 200 met een JSON-antwoordtekst. Het retourneren van item resulteert in een HTTP 200 antwoord.

De methode PutTodoItem

Bekijk de PutTodoItem methode:

[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 is vergelijkbaar met PostTodoItem, met uitzondering van HTTP PUT. Het antwoord is 204 (geen inhoud). Volgens de HTTP-specificatie vereist een PUT aanvraag dat de client de volledige bijgewerkte entiteit verzendt, niet alleen de wijzigingen. Gebruik HTTP PATCH-om gedeeltelijke updates te ondersteunen.

De methode PutTodoItem testen

In dit voorbeeld wordt een in-memory database gebruikt die telkens wanneer de app wordt gestart, moet worden geïnitialiseerd. Er moet een item in de database staan voordat u een PUT-aanroep uitvoert. Roep GET aan om ervoor te zorgen dat er een item in de database staat voordat u een PUT-aanroep doet.

Gebruik de Swagger UI om de TodoItem met id = 1 bij te werken door de PUT-knop te gebruiken en stel de naam in op "feed fish". Let op: het antwoord is HTTP 204 No Content.

De methode DeleteTodoItem

Bekijk de DeleteTodoItem methode:

[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();
}

De methode DeleteTodoItem testen

Gebruik de Swagger-gebruikersinterface om de TodoItem met Id = 1 te verwijderen. Let op: het antwoord is HTTP 204 No Content.

Testen met andere hulpprogramma's

Er zijn veel andere hulpprogramma's die kunnen worden gebruikt om web-API's te testen, bijvoorbeeld:

Zie voor meer informatie:

Overmatig posten voorkomen

Op dit moment wordt in de voorbeeld-app het hele TodoItem-object weergegeven. Productie-apps beperken doorgaans de gegevens die worden ingevoerd en geretourneerd met behulp van een subset van het model. Er zijn meerdere redenen achter dit, en beveiliging is een belangrijke. De subset van een model wordt meestal aangeduid als een DTO (Data Transfer Object), invoermodel of weergavemodel. DTO- wordt in deze handleiding gebruikt.

Een DTO kan worden gebruikt voor het volgende:

  • Voorkom overposten.
  • Eigenschappen verbergen die klanten niet zouden moeten zien.
  • Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
  • Maak objectgrafen plat die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.

Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem klasse bij om een geheim veld op te nemen:

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

Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.

Controleer of u het geheime veld kunt plaatsen en verkrijgen.

Een DTO-model maken:

namespace TodoApi.Models;

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

Werk de TodoItemsController bij om TodoItemDTOte gebruiken:

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

Controleer of u het geheime veld niet kunt posten of ophalen.

De web-API aanroepen met JavaScript

Zie zelfstudie: Een ASP.NET Core-web-API aanroepen met JavaScript-.

Web-API-videoserie

Zie Video: Beginnersserie van Web-API's.

Patronen voor bedrijfsweb-apps

Zie Enterprise-web-app-patronenvoor hulp bij het maken van een betrouwbare, veilige, uitvoerbare, testbare en schaalbare ASP.NET Core-app. Er is een volledige voorbeeldweb-app van productiekwaliteit beschikbaar waarmee de patronen worden geïmplementeerd.

Verificatieondersteuning toevoegen aan een web-API

ASP.NET Core Identity voegt de aanmeldingsfunctionaliteit van de gebruikersinterface (UI) toe aan ASP.NET Core-web-apps. Gebruik een van de volgende manieren om web-API's en SPA's te beveiligen:

Duende Identity Server is een OpenID Connect- en OAuth 2.0-framework voor ASP.NET Core. Duende Identity Server maakt de volgende beveiligingsfuncties mogelijk:

  • Verificatie als een service (AaaS)
  • Eenmalige aanmelding/uit (SSO) voor meerdere toepassingstypen
  • Toegangsbeheer voor API's
  • Federatie-gateway

Belangrijk

Duende Software moet u mogelijk een licentiekosten betalen voor productiegebruik van Duende Identity Server. Zie Migreren van ASP.NET Core 5.0 naar 6.0voor meer informatie.

Zie de Duende Identity Server-documentatie (Duende Software-website)voor meer informatie.

Publiceren naar Azure

Zie Quickstart: Een ASP.NET-web-app implementerenvoor meer informatie over het implementeren in Azure.

Aanvullende informatiebronnen

Bekijk of download de voorbeeldcode voor deze tutorial. Zie hoe u kunt downloaden.

Zie de volgende bronnen voor meer informatie: