Delen via


Zelfstudie: Een web-API 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 Rick Anderson en Kirk Larkin

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 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 de Framework- is .NET 8.0 (Langetermijnondersteuning).
    • 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 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 naam van 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.

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 voor meer informatie kenmerkroutering met Http[werkwoord]-attributen.

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 ukunt 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 handleiding maakt u de volgende API:

API Beschrijving Aanvraaginhoud Antwoordlichaam
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 vervolgens Volgende.
  • Geef in het dialoogvenster Uw nieuwe project configurerende naam aan het project TodoApi en selecteer Volgende.
  • In het dialoogvenster Aanvullende informatie:
    • Bevestig dat de Framework- is .NET 8.0 (Langetermijnondersteuning).
    • 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 rechterpaneel en selecteer vervolgens Installeren.

Notitie

Zie de artikelen onder Pakketten installeren en beheren bij Verbruikswerkstroom voor pakketten (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 Haal>Probeer het uit>Voer uit. 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 af te leiden 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 de API-controller met acties toevoegen met behulp van het dialoogvenster Entity Framework:

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

    Als de scaffolding mislukt, selecteert u Toevoegen om te proberen 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.
  • [action] is niet opgenomen in de routesjabloon van API-controllers.

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 'create'-methode van PostTodoItem bijwerken

Werk de return statement 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.

Voor meer informatie, zie attribuutsroutering met Http[werkwoord]-kenmerken.

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 UI de locatieheader onder antwoordheaders. 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 uitvoeren.

    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 de-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. Voor meer informatie, zie attribuutroutering met Http[werkwoord]-attributen.

In de volgende GetTodoItem-methode is "{id}" een tijdelijke aanduiding voor de unieke ID van het to-do-item. 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-gebruikersinterface en druk op de PUT-knop om de TodoItem met Id = 1 bij te werken en stel de naam in op "feed fish". Let op: het antwoord is HTTP 204 No Content.

De methode DeleteTodoItem

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

De methode DeleteTodoItem testen

Gebruik de Swagger UI 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 zelfstudie gebruikt.

Een DTO kan worden gebruikt voor het volgende:

  • Voorkom overmatig plaatsen.
  • Eigenschappen verbergen die klanten niet mogen 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 plaatsen en opvragen.

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: Beginners-reeks voor 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 voorbeeldcode voor deze handleiding. Zie hoe ukunt 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 zelfstudie maak je de volgende API:

API Beschrijving Aanvraaginhoud 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 Actiepunt 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

  • In het menu Bestand, selecteer Nieuw>Project.
  • Voer Web-API- in het zoekvak in.
  • Kies de sjabloon ASP.NET Core Web API en klik op Volgende.
  • Geef in het dialoogvenster Configureer uw nieuwe projectde naam van het project TodoApi en selecteer Volgende.
  • In het dialoogvenster Aanvullende informatie:
    • Controleer of de Framework- is .NET 8.0 (Langetermijnondersteuning).
    • 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 , maak.

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.
  • Vink in het rechterdeelvenster het selectievakje Project aan en selecteer vervolgens Installeren.

Notitie

Zie de artikelen onder Pakketten installeren en beheren bij Workflow voor pakketconsumptie (NuGet-documentatie)voor begeleiding 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 gecreëerd 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.

Maak een basisstructuur voor 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 de API-controller met acties toevoegen met behulp van het dialoogvenster Entity Framework:

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

    Als de steigerconstructie mislukt, selecteert u Toevoegen om de steigerconstructie nogmaals 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 het 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.

Werk de PostTodoItem-aanmaakmethode bij

Werk de retourinstructie in de PostTodoItem bij om de naam van 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 locatieheader onder Antwoordheaders. 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 Uitvoeren.

    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 teruggestuurd, 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. Voor meer informatie, zie Kenmerkroutering met Http[Werkwoord]-kenmerken.

In de volgende methode GetTodoItem is "{id}" een tijdelijke aanduiding voor de unieke identificatie van het to-do-item. 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 methode 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 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 UI 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 plaatsen 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 zelfstudie gebruikt.

Een DTO kan worden gebruikt voor het volgende:

  • Voorkom overmatig posten.
  • Eigenschappen verbergen die klanten niet mogen 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 voor 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
  • Federatieve 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

Voorbeeldcode voor deze zelfstudie weergeven of downloaden. Zie hoe ukunt downloaden.

Zie de volgende bronnen voor meer informatie: