Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Note
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikel voor de huidige release.
Warning
Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.
Important
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 artikel voor de huidige release.
By Tim Deschryver and Rick Anderson
In deze zelfstudie leert u de basisbeginselen van het bouwen van een web-API op basis van een controller die gebruikmaakt van een database. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. Zie zelfstudie: Een minimale API maken met ASP.NET Core voor een zelfstudie over het maken van een minimale API.
Overview
In deze tutorial maak je de volgende API aan:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Alle to-do items ophalen | None | Reeks van to-do items |
GET /api/todoitems/{id} |
Een item ophalen met ID | None | To-do item |
POST /api/todoitems |
Een nieuw item toevoegen | To-do item | To-do item |
PUT /api/todoitems/{id} |
Een bestaand item bijwerken | To-do item | None |
DELETE /api/todoitems/{id} |
Een item verwijderen | None | None |
In het volgende diagram ziet u het ontwerp van de app.
Prerequisites
Visual Studio 2022 met de ASP.NET en webontwikkeling-workload.
Een web-API-project maken
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Selecteer de ASP.NET Core Web API-sjabloon en selecteer Volgende.
- Geef in het dialoogvenster Uw nieuwe project configureren de naam van het project TodoApi en selecteer Volgende.
- In the Additional information dialog:
- Confirm the Framework is .NET 9.0 (Standard Term Support).
- Controleer of het selectievakje voor OpenAPI-ondersteuning inschakelen is ingeschakeld.
- Controleer of het selectievakje voor Controllers gebruiken (schakel het selectievakje uit om minimale API's te gebruiken) is ingeschakeld.
- Select Create.
Een NuGet-pakket toevoegen
Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptieworkflow (NuGet-documentatie) voor hulp bij het toevoegen van pakketten aan .NET-apps. Confirm correct package versions at NuGet.org.
Het project uitvoeren
The project template creates a WeatherForecast
API with support for OpenAPI.
Druk op Ctrl+F5 om uit te voeren zonder het foutopsporingsprogramma.
Visual Studio geeft het volgende dialoogvenster weer wanneer een project nog niet is geconfigureerd voor het gebruik van SSL:
Select Yes if you trust the IIS Express SSL certificate.
Het volgende dialoogvenster wordt weergegeven:
Select Yes if you agree to trust the development certificate.
Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfout voor meer informatie over het vertrouwen van de Firefox-browser.
Visual Studio start een terminalvenster en geeft de URL van de actieve app weer. De API wordt gehost op https://localhost:<port>
, waarbij <port>
een willekeurig gekozen poortnummer is dat is ingesteld bij het maken van het project.
...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:7260
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:7261
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
...
Ctrl+click the HTTPS URL in the output to test the web app in a browser. Er is geen eindpunt op https://localhost:<port>
, dus de browser retourneert HTTP 404 Niet gevonden.
Voeg /weatherforecast
toe aan de URL om de WeatherForecast-API te testen.
In de browser wordt JSON weergegeven die vergelijkbaar is met het volgende voorbeeld:
[
{
"date": "2025-07-16",
"temperatureC": 52,
"temperatureF": 125,
"summary": "Mild"
},
{
"date": "2025-07-17",
"temperatureC": 36,
"temperatureF": 96,
"summary": "Warm"
},
{
"date": "2025-07-18",
"temperatureC": 39,
"temperatureF": 102,
"summary": "Cool"
},
{
"date": "2025-07-19",
"temperatureC": 10,
"temperatureF": 49,
"summary": "Bracing"
},
{
"date": "2025-07-20",
"temperatureC": -1,
"temperatureF": 31,
"summary": "Chilly"
}
]
Het project testen
In deze zelfstudie worden Endpoints Explorer- en HTTP-bestanden gebruikt om de API te testen.
Een modelklasse toevoegen
A model is a set of classes that represent the data that the app manages. Het model voor deze app is de TodoItem
klasse.
- In Solution Explorer, right-click the project. Select Add>New Folder. Geef de map een naam
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - 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
The database context is the main class that coordinates Entity Framework functionality for a data model. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.
Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.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 afhankelijkheidsinjectiecontainer (DI ). De container biedt de service aan controllers.
Werk Program.cs
bij met de volgende gemarkeerde code:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApi();
builder.Services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
De voorgaande code:
- Voegt
using
richtlijnen toe. - Voegt de databasecontext toe aan de DI-container.
- Hiermee geeft u op dat de databasecontext een in-memory database gebruikt.
Genereer een controller
Klik met de rechtermuisknop op de map
Controllers
.Select Add>New Scaffolded Item.
Selecteer API-controller met acties, met behulp van Entity Framework en selecteer vervolgens Toevoegen.
In het dialoogvenster API-controller toevoegen met acties, met behulp van Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
Met deze stap worden de Microsoft.VisualStudio.Web.CodeGeneration.Design
- en Microsoft.EntityFrameworkCore.Tools
NuGet-pakketten aan het project toegevoegd.
Deze pakketten zijn vereist voor steigerbouw.
De gegenereerde code:
- Markeert de klasse met het kenmerk
[ApiController]
. Dit kenmerk geeft aan dat de controller reageert op web-API-aanvragen. Zie Web-API's maken met ASP.NET Core voor informatie over specifiek gedrag dat het kenmerk inschakelt. - Maakt gebruik van DI om de databasecontext (
TodoContext
) in de controller te injecteren. The database context is used in each of the CRUD methods in the controller.
De ASP.NET Core-sjablonen voor:
- Controllers met weergaven bevatten
[action]
in de routesjabloon. - API-controllers bevatten geen
[action]
in de routesjabloon.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. 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
Update the return statement in the PostTodoItem
to use the nameof operator:
[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]-kenmerken voor 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. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Zie 10.2.2 2 201 Gemaakt voor 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.
Test PostTodoItem
Select View>Other Windows>Endpoints Explorer.
Right-click the POST endpoint and select Generate request.
Er wordt een nieuw bestand gemaakt in de projectmap met de naam
TodoApi.http
, met inhoud die vergelijkbaar is met het volgende voorbeeld:@TodoApi_HostAddress = https://localhost:49738 POST {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { //TodoItem } ###
- Met de eerste regel maakt u een variabele die wordt gebruikt voor alle eindpunten.
- De volgende regel definieert een POST-aanvraag.
- De regels na de POST-aanvraagregel definiëren de headers en een tijdelijke aanduiding voor de aanvraagbody.
- De regel met de drievoudige hashtag (
###
) is een scheidingsteken voor aanvragen: wat erna komt, is voor een andere aanvraag.
De POST-aanvraag verwacht een
TodoItem
. Om de todo te definiëren, vervangt u de//TodoItem
opmerking door de volgende JSON:{ "name": "walk dog", "isComplete": true }
Het todoApi.http-bestand moet er nu uitzien zoals in het volgende voorbeeld, maar met uw poortnummer:
@TodoApi_HostAddress = https://localhost:7260 Post {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { "name": "walk dog", "isComplete": true } ###
Voer de app uit.
Select the Send request link that is above the
POST
request line.The POST request is sent to the app and the response is displayed in the Response pane.
De URI van de locatieheader testen
Test the app by calling the GET
endpoints from a browser or by using Endpoints Explorer. The following steps are for Endpoints Explorer.
In Endpoints Explorer, right-click the first GET endpoint, and select Generate request.
De volgende inhoud wordt toegevoegd aan het
TodoApi.http
-bestand:GET {{TodoApi_HostAddress}}/api/todoitems ###
Select the Send request link that is above the new
GET
request line.The GET request is sent to the app and the response is displayed in the Response pane.
De hoofdtekst van het antwoord is vergelijkbaar met de volgende JSON:
[ { "id": 1, "name": "walk dog", "isComplete": true } ]
In Endpoints Explorer, right-click the
/api/todoitems/{id}
GET endpoint and select Generate request. De volgende inhoud wordt toegevoegd aan hetTodoApi.http
-bestand:@id=0 GET {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Wijs
{@id}
toe aan1
(in plaats van0
).Select the Send request link that is above the new GET request line.
The GET request is sent to the app and the response is displayed in the Response pane.
De hoofdtekst van het antwoord is vergelijkbaar met de volgende JSON:
{ "id": 1, "name": "walk dog", "isComplete": true }
De GET-methoden onderzoeken
Er worden twee GET-eindpunten geïmplementeerd:
GET /api/todoitems
GET /api/todoitems/{id}
In de vorige sectie is een voorbeeld van de /api/todoitems/{id}
route getoond.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. If no data is returned, POST data to the 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'. For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Als het kenmerk
[HttpGet]
een routesjabloon heeft (bijvoorbeeld[HttpGet("products")]
), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie Kenmerkroutering met http[werkwoord]-kenmerken voor meer informatie.
In de volgende GetTodoItem
-methode is "{id}"
een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem
wordt aangeroepen, wordt de waarde van "{id}"
in de URL verstrekt aan de methode in de parameter id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Het retourtype van de GetTodoItems
en GetTodoItem
methoden is ActionResult<T-type>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. 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:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- 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. To support partial updates, use HTTP PATCH.
De methode PutTodoItem testen
In dit voorbeeld wordt een in-memory database gebruikt die telkens wanneer de app wordt gestart, moet worden geïnitialiseerd. Er moet een item in de database staan voordat u een PUT-aanroep uitvoert. Roep GET aan om ervoor te zorgen dat er een item in de database staat voordat u een PUT-aanroep doet.
Gebruik de methode PUT
om de TodoItem
met id = 1 bij te werken en de naam ervan in te stellen op "feed fish"
. Let op: het antwoord is HTTP 204 No Content
.
In Endpoints Explorer, right-click the PUT endpoint, and select Generate request.
De volgende inhoud wordt toegevoegd aan het
TodoApi.http
-bestand:PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}} Content-Type: application/json { //TodoItem } ###
Vervang
{{id}}
in de PUT-aanvraagregel door1
.Vervang de tijdelijke aanduiding
//TodoItem
door de volgende regels:PUT {{TodoApi_HostAddress}}/api/todoitems/1 Content-Type: application/json { "id": 1, "name": "feed fish", "isComplete": false }
Select the Send request link that is above the new PUT request line.
The PUT request is sent to the app and the response is displayed in the Response pane. De hoofdtekst van het antwoord is leeg en de statuscode is 204.
De methode DeleteTodoItem
Bekijk de DeleteTodoItem
methode:
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
De methode DeleteTodoItem testen
Gebruik de methode DELETE
om de TodoItem
met id = 1 te verwijderen. Let op: het antwoord is HTTP 204 No Content
.
In Endpoints Explorer, right-click the DELETE endpoint and select Generate request.
Er wordt een DELETE-aanvraag toegevoegd aan
TodoApi.http
.Vervang
{{id}}
in de regel van de DELETE-aanvraag door1
. De DELETE-aanvraag moet eruitzien als in het volgende voorbeeld:DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Select the Send request link for the DELETE request.
The DELETE request is sent to the app and the response is displayed in the Response pane. De hoofdtekst van het antwoord is leeg en de statuscode is 204.
Testen met andere hulpprogramma's
Er zijn veel andere hulpprogramma's die kunnen worden gebruikt om web-API's te testen, bijvoorbeeld:
Prevent over-posting
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 is used in this tutorial.
Een DTO kan worden gebruikt voor het volgende:
- Prevent over-posting.
- Eigenschappen verbergen die klanten niet zouden moeten zien.
- Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
- Maak objectgrafieken plat die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.
Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem
klasse bij om een geheim veld op te nemen:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.
Controleer of u de geheime veldgegevens kunt plaatsen en ophalen.
Create a DTO model in a Models/TodoItemsDTO.cs file:
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: Beginnersreeks voor: Web-API's.
Patronen voor bedrijfsweb-apps
Zie Enterprise-web-apppatronen voor hulp bij het maken van een betrouwbare, veilige, performante, 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
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Zie Migreren van ASP.NET Core in .NET 5 naar .NET 6 voor meer informatie.
Zie de documentatie van Duende Server (Duende Identity Software-website) voor meer informatie.
Publiceren naar Azure
Zie quickstart: Een ASP.NET-web-app implementeren voor meer informatie over het implementeren in Azure.
Additional resources
Bekijk of download voorbeeldcode voor deze zelfstudie. Zie hoe te 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
- De gegenereerde OpenAPI-documenten gebruiken
- ASP.NET Core web-API-documentatie met Swagger/OpenAPI
- Razor Pagina's met Entity Framework Core in ASP.NET Core - Zelfstudie 1 van 8
- Routeren naar controlleracties in ASP.NET Core
- Returntypen van controlleracties in ASP.NET Core-web-API
- ASP.NET Core-apps implementeren in Azure App Service
- ASP.NET Core hosten en 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. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. Zie zelfstudie: Een minimale API maken met ASP.NET Core voor een zelfstudie over het maken van een minimale API.
Overview
In deze tutorial maak je de volgende API aan:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Alle to-do items ophalen | None | Reeks van to-do items |
GET /api/todoitems/{id} |
Een item ophalen met ID | None | To-do item |
POST /api/todoitems |
Een nieuw item toevoegen | To-do item | To-do item |
PUT /api/todoitems/{id} |
Een bestaand item bijwerken | To-do item | None |
DELETE /api/todoitems/{id} |
Een item verwijderen | None | None |
In het volgende diagram ziet u het ontwerp van de app.
Prerequisites
Visual Studio 2022 met de ASP.NET en webontwikkeling-workload.
Een webproject maken
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Selecteer de ASP.NET Core Web API-sjabloon en selecteer Volgende.
- Geef in het dialoogvenster Uw nieuwe project configureren de naam van het project TodoApi en selecteer Volgende.
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- 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.
- Select Create.
Een NuGet-pakket toevoegen
Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptieworkflow (NuGet-documentatie) voor hulp bij het toevoegen van pakketten aan .NET-apps. Confirm correct package versions at NuGet.org.
Het project testen
The project template creates a WeatherForecast
API with support for 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:
Select Yes if you trust the IIS Express SSL certificate.
Het volgende dialoogvenster wordt weergegeven:
Select Yes if you agree to trust the development certificate.
Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfout voor 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. Select GET>Try it out>Execute. Op de pagina wordt het volgende weergegeven:
- The Curl command to test the WeatherForecast API.
- 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.
Copy and paste the Request URL in the 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
A model is a set of classes that represent the data that the app manages. Het model voor deze app is de TodoItem
klasse.
- In Solution Explorer, right-click the project. Select Add>New Folder. Geef de map een naam
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - 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
The database context is the main class that coordinates Entity Framework functionality for a data model. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.
- Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.
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 afhankelijkheidsinjectiecontainer (DI ). 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
.Select Add>New Scaffolded Item.
Selecteer API-controller met acties, met behulp van Entity Framework en selecteer vervolgens Toevoegen.
In het dialoogvenster API-controller toevoegen met acties, met behulp van Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
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 Core voor informatie over specifiek gedrag dat het kenmerk inschakelt. - Maakt gebruik van DI om de databasecontext (
TodoContext
) in de controller te injecteren. The database context is used in each of the CRUD methods in the controller.
De ASP.NET Core-sjablonen voor:
- Controllers met weergaven bevatten
[action]
in de routesjabloon. - API-controllers bevatten geen
[action]
in de routesjabloon.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. 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
Update the return statement in the PostTodoItem
to use the nameof operator:
[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]-kenmerken voor 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. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Zie 10.2.2 2 201 Gemaakt voor 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.
Test PostTodoItem
Druk op Ctrl+F5 om de app uit te voeren.
In the Swagger browser window, select POST /api/TodoItems, and then select Try it out.
In the Request body input window, update the JSON. For example,
{ "name": "walk dog", "isComplete": true }
Select Execute
De URI van de locatieheader testen
In the preceding POST, the Swagger UI shows the location header under Response headers. Bijvoorbeeld location: https://localhost:7260/api/TodoItems/1
. De locatieheader toont de URI voor de gemaakte resource.
De locatiekoptekst testen:
In the Swagger browser window, select GET /api/TodoItems/{id}, and then select Try it out.
Enter
1
in theid
input box, and then select Execute.
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.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. If no data is returned, POST data to the 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'. For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Als het kenmerk
[HttpGet]
een routesjabloon heeft (bijvoorbeeld[HttpGet("products")]
), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie Kenmerkroutering met http[werkwoord]-kenmerken voor meer informatie.
In de volgende GetTodoItem
-methode is "{id}"
een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem
wordt aangeroepen, wordt de waarde van "{id}"
in de URL verstrekt aan de methode in de parameter id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Het retourtype van de GetTodoItems
en GetTodoItem
methoden is ActionResult<T-type>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. 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:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- 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. To support partial updates, use HTTP PATCH.
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:
Prevent over-posting
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 is used in this tutorial.
Een DTO kan worden gebruikt voor het volgende:
- Prevent over-posting.
- Eigenschappen verbergen die klanten niet zouden moeten zien.
- Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
- Maak objectgrafieken plat die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.
Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem
klasse bij om een geheim veld op te nemen:
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
}
Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.
Controleer of u de geheime veldgegevens kunt plaatsen 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: Beginnersreeks voor: Web-API's.
Patronen voor bedrijfsweb-apps
Zie Enterprise-web-apppatronen voor hulp bij het maken van een betrouwbare, veilige, performante, 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
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Zie Migreren van ASP.NET Core in .NET 5 naar .NET 6 voor meer informatie.
Zie de documentatie van Duende Server (Duende Identity Software-website) voor meer informatie.
Publiceren naar Azure
Zie quickstart: Een ASP.NET-web-app implementeren voor meer informatie over het implementeren in Azure.
Additional resources
Bekijk of download voorbeeldcode voor deze zelfstudie. Zie hoe te 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
- Routeren naar controlleracties in ASP.NET Core
- Returntypen van controlleracties in ASP.NET Core-web-API
- ASP.NET Core-apps implementeren in Azure App Service
- ASP.NET Core hosten en 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. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. Zie zelfstudie: Een minimale API maken met ASP.NET Core voor een zelfstudie over het maken van een minimale API.
Overview
In deze tutorial maak je de volgende API aan:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Alle to-do items ophalen | None | Reeks van to-do items |
GET /api/todoitems/{id} |
Een item ophalen met ID | None | To-do item |
POST /api/todoitems |
Een nieuw item toevoegen | To-do item | To-do item |
PUT /api/todoitems/{id} |
Een bestaand item bijwerken | To-do item | None |
DELETE /api/todoitems/{id} |
Een item verwijderen | None | None |
In het volgende diagram ziet u het ontwerp van de app.
Prerequisites
Visual Studio 2022 met de ASP.NET en webontwikkeling-workload.
Een webproject maken
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Selecteer de ASP.NET Core Web API-sjabloon en selecteer Volgende.
- Geef in het dialoogvenster Uw nieuwe project configureren de naam van het project TodoApi en selecteer Volgende.
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- 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.
- Select Create.
Een NuGet-pakket toevoegen
Er moet een NuGet-pakket worden toegevoegd ter ondersteuning van de database die in deze zelfstudie wordt gebruikt.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Zie de artikelen onder Pakketten installeren en beheren bij Pakketconsumptieworkflow (NuGet-documentatie) voor hulp bij het toevoegen van pakketten aan .NET-apps. Confirm correct package versions at NuGet.org.
Het project testen
The project template creates a WeatherForecast
API with support for 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:
Select Yes if you trust the IIS Express SSL certificate.
Het volgende dialoogvenster wordt weergegeven:
Select Yes if you agree to trust the development certificate.
Zie Firefox SEC_ERROR_INADEQUATE_KEY_USAGE certificaatfout voor 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. Select GET>Try it out>Execute. Op de pagina wordt het volgende weergegeven:
- The Curl command to test the WeatherForecast API.
- 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.
Copy and paste the Request URL in the 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
A model is a set of classes that represent the data that the app manages. Het model voor deze app is de TodoItem
klasse.
- In Solution Explorer, right-click the project. Select Add>New Folder. Geef de map een naam
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - 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
The database context is the main class that coordinates Entity Framework functionality for a data model. Deze klasse wordt gemaakt door te erven van de Microsoft.EntityFrameworkCore.DbContext klasse.
- Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.
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 afhankelijkheidsinjectiecontainer (DI ). 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
.Select Add>New Scaffolded Item.
Selecteer API-controller met acties, met behulp van Entity Framework en selecteer vervolgens Toevoegen.
In het dialoogvenster API-controller toevoegen met acties, met behulp van Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
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 Core voor informatie over specifiek gedrag dat het kenmerk inschakelt. - Maakt gebruik van DI om de databasecontext (
TodoContext
) in de controller te injecteren. The database context is used in each of the CRUD methods in the controller.
De ASP.NET Core-sjablonen voor:
- Controllers met weergaven bevatten
[action]
in de routesjabloon. - API-controllers bevatten geen
[action]
in de routesjabloon.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. 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
Update the return statement in the PostTodoItem
to use the nameof operator:
[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]-kenmerken voor 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. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Zie 10.2.2 2 201 Gemaakt voor 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.
Test PostTodoItem
Druk op Ctrl+F5 om de app uit te voeren.
In the Swagger browser window, select POST /api/TodoItems, and then select Try it out.
In the Request body input window, update the JSON. For example,
{ "name": "walk dog", "isComplete": true }
Select Execute
De URI van de locatieheader testen
In the preceding POST, the Swagger UI shows the location header under Response headers. Bijvoorbeeld location: https://localhost:7260/api/TodoItems/1
. De locatieheader toont de URI voor de gemaakte resource.
De locatiekoptekst testen:
In the Swagger browser window, select GET /api/TodoItems/{id}, and then select Try it out.
Enter
1
in theid
input box, and then select Execute.
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.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Deze app maakt gebruik van een in-memory database. Als de app is gestopt en gestart, retourneert de voorgaande GET-aanvraag geen gegevens. If no data is returned, POST data to the 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'. For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Als het kenmerk
[HttpGet]
een routesjabloon heeft (bijvoorbeeld[HttpGet("products")]
), voegt u dit toe aan het pad. In dit voorbeeld wordt geen sjabloon gebruikt. Zie Kenmerkroutering met http[werkwoord]-kenmerken voor meer informatie.
In de volgende GetTodoItem
-methode is "{id}"
een placeholder voor de unieke identificatie van het item to-do. Wanneer GetTodoItem
wordt aangeroepen, wordt de waarde van "{id}"
in de URL verstrekt aan de methode in de parameter id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Het retourtype van de GetTodoItems
en GetTodoItem
methoden is ActionResult<T-type>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. 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:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- 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. To support partial updates, use HTTP PATCH.
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:
Prevent over-posting
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 is used in this tutorial.
Een DTO kan worden gebruikt voor het volgende:
- Prevent over-posting.
- Eigenschappen verbergen die klanten niet zouden moeten zien.
- Laat bepaalde eigenschappen weg om de nettolading te verkleinen.
- Maak objectgrafieken plat die geneste objecten bevatten. Platgemaakte objectgrafieken kunnen handiger zijn voor clients.
Als u de DTO-benadering wilt demonstreren, werkt u de TodoItem
klasse bij om een geheim veld op te nemen:
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
}
Het geheime veld moet worden verborgen voor deze app, maar een beheer-app kan ervoor kiezen om het beschikbaar te maken.
Controleer of u de geheime veldgegevens kunt plaatsen 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: Beginnersreeks voor: Web-API's.
Patronen voor bedrijfsweb-apps
Zie Enterprise-web-apppatronen voor hulp bij het maken van een betrouwbare, veilige, performante, 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
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Zie Migreren van ASP.NET Core in .NET 5 naar .NET 6 voor meer informatie.
Zie de documentatie van Duende Server (Duende Identity Software-website) voor meer informatie.
Publiceren naar Azure
Zie quickstart: Een ASP.NET-web-app implementeren voor meer informatie over het implementeren in Azure.
Additional resources
Bekijk of download voorbeeldcode voor deze zelfstudie. Zie hoe te 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
- Routeren naar controlleracties in ASP.NET Core
- Returntypen van controlleracties in ASP.NET Core-web-API
- ASP.NET Core-apps implementeren in Azure App Service
- ASP.NET Core hosten en implementeren
- Een web-API maken met ASP.NET Core