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.
Voorwaarden
Visual Studio 2022 met de ASP.NET- en webontwikkelingsworkload.
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:
Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.
Het volgende dialoogvenster wordt weergegeven:
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 eenHTTP 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 deLocation
header te maken. Het trefwoord C#nameof
wordt gebruikt om te voorkomen dat de actienaam in deCreatedAtAction
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
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 invoervakid
in en selecteer omuit te voeren.
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 eenHTTP 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:
- Visual Studio Endpoints Explorer en HTTP-bestanden
- http-repl
-
curl. Swagger gebruikt
curl
en toont decurl
opdrachten die worden verzonden. - Fiddler
Zie voor meer informatie:
- zelfstudie over minimale API: testen met .http-bestanden en Endpoints Explorer-
-
API's installeren en testen met
http-repl
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 TodoItemDTO
te 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:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
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:
- Web-API's maken met ASP.NET Core-
- Zelfstudie: Een minimale API maken met ASP.NET Core
- ASP.NET Core web-API-documentatie met Swagger/OpenAPI-
- Razor Pagina's met Entity Framework Core in ASP.NET Core - Zelfstudie 1 van 8
- Routing naar controller-acties in ASP.NET Core
- Actieresultatentypen van controllers in ASP.NET Core Web-API
- ASP.NET Core-apps implementeren in Azure App Service-
- Hosten en ASP.NET Core- implementeren
- Een web-API maken met ASP.NET Core
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.
Voorwaarden
Visual Studio 2022 met de ASP.NET- en webontwikkelingsworkload.
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:
Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.
Het volgende dialoogvenster wordt weergegeven:
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 eenHTTP 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 deLocation
header te maken. Het trefwoord C#nameof
wordt gebruikt om te voorkomen dat de actienaam in deCreatedAtAction
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
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 invoervakid
in en selecteer uitvoeren.
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 eenHTTP 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:
- Visual Studio Endpoints Explorer en .http-bestanden
- http-repl-
-
curl. Swagger gebruikt
curl
en toont decurl
opdrachten die worden verzonden. - Fiddler
Zie voor meer informatie:
- zelfstudie over minimale API: testen met .http-bestanden en Endpoints Explorer-
-
API's installeren en testen met
http-repl
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 TodoItemDTO
te 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:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server-
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:
- Web-API's maken met ASP.NET Core-
- Zelfstudie: Een minimale API maken met ASP.NET Core
- ASP.NET Core web-API-documentatie met Swagger/OpenAPI-
- Razor Pagina's met Entity Framework Core in ASP.NET Core - Zelfstudie 1 van 8
- Routing naar controller-acties in ASP.NET Core
- Retourswaarden voor acties van controllers in ASP.NET Core web API
- ASP.NET Core-apps implementeren in Azure App Service-
- Hosten en ASP.NET Core- implementeren
- Een web-API maken met ASP.NET Core
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.
Voorwaarden
Visual Studio 2022 met de ASP.NET- en webontwikkelingsworkload.
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:
Selecteer Ja als u het IIS Express SSL-certificaat vertrouwt.
Het volgende dialoogvenster wordt weergegeven:
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 eenHTTP 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 deLocation
header te maken. Het trefwoord C#nameof
wordt gebruikt om te voorkomen dat de actienaam in deCreatedAtAction
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
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 invoervakid
in en selecteer Uitvoeren.
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 eenHTTP 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:
- Visual Studio Endpoints Explorer en HTTP-bestanden
- http-repl
-
curl. Swagger gebruikt
curl
en toont decurl
opdrachten die worden verzonden. - Fiddler
Zie voor meer informatie:
- zelfstudie over minimale API: testen met .http-bestanden en Endpoints Explorer-
-
API's installeren en testen met
http-repl
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 TodoItemDTO
te 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:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
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:
- Web-API's maken met ASP.NET Core-
- Zelfstudie: Een minimale API maken met ASP.NET Core
- ASP.NET Core web-API-documentatie met Swagger/OpenAPI-
- Razor Pagina's met Entity Framework Core in ASP.NET Core - Zelfstudie 1 van 8
- routering naar controlleracties in ASP.NET Core
- nl-NL: Controlleractie-retourtypen in ASP.NET Core Web API
- ASP.NET Core-apps implementeren in Azure App Service-
- Hosten en ASP.NET Core- implementeren
- Een web-API maken met ASP.NET Core