Tutorial: Erstellen einer Web-API mit ASP.NET Core
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Von Rick Anderson und Kirk Larkin
In diesem Tutorial lernen Sie die Grundlagen der Erstellung einer controllerbasierten Web-API, die eine Datenbank verwendet. Ein anderer Ansatz zum Erstellen von APIs in ASP.NET Core besteht in der Erstellung von minimalen APIs. Hilfe bei der Entscheidung zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Anleitungen zum Erstellen einer minimalen API finden Sie im Tutorial: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
API | Beschreibung | Anforderungstext | Antworttext |
---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | Keine | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | Keine | To-do-Element |
POST /api/todoitems |
Neues Element hinzufügen | To-do-Element | To-do-Element |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | To-do-Element | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit der Workload ASP.NET und Webentwicklung
Erstellen eines Webprojekts
- Klicken Sie im Menü Datei auf Neu>Projekt.
- Geben Sie Web-API in das Suchfeld ein.
- Wählen Sie die ASP.NET Core-Web-API-Vorlage aus, und klicken Sie auf Weiter.
- Geben Sie im Dialogfeld Neues Projekt konfigurieren dem Projekt den Namen TodoApi, und wählen Sie dann Weiter aus.
- Im Dialogfeld Zusätzliche Informationen:
- Bestätigen Sie, dass das Framework auf .NET 8.0 (Langfristiger Support) festgelegt ist.
- Vergewissern Sie sich, dass das Kontrollkästchen Controller verwenden (zur Verwendung minimaler APIs deaktivieren) aktiviert ist.
- Vergewissern Sie sich, dass das Kontrollkästchen OpenAPI-Unterstützung aktivieren aktiviert ist.
- Klicken Sie auf Erstellen.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Klicken Sie im Menü Extras auf NuGet-Paket-Manager > NuGet-Pakete für Projektmappe verwalten.
- Wählen Sie die Registerkarte Durchsuchen aus.
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
aus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Hinweis
Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Testen des Projekts
Die Projektvorlage erstellt eine WeatherForecast
-API mit Unterstützung für Swagger.
Drücken Sie STRG+F5, um die Ausführung ohne den Debugger zu starten.
Visual Studio zeigt das folgende Dialogfeld an, wenn ein Projekt noch nicht für die Verwendung von SSL konfiguriert ist:
Wählen Sie Ja aus, wenn Sie dem IIS Express-SLL-Zertifikat vertrauen möchten.
Das folgende Dialogfeld wird angezeigt:
Klicken Sie auf Ja, wenn Sie zustimmen möchten, dass das Entwicklungszertifikat vertrauenswürdig ist.
Informationen dazu, wie Sie dem Firefox-Browser vertrauen, finden Sie unter Firefox-Zertifikatfehler SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio startet einen Standardbrowser und navigiert zu https://localhost:<port>/swagger/index.html
, wobei es sich bei <port>
um eine zufällig ausgewählte Portnummer handelt.
Die Swagger-Seite /swagger/index.html
wird angezeigt. Wählen Sie GET>Tryit out>Execute (GET > Testen> Ausführen) aus. Die Seite zeigt Folgendes an:
- Der Curl-Befehl, zum Testen der WeatherForecast-API.
- Die URL zum Testen der WeatherForecast-API.
- Der Antwortcode, der Text und die Header.
- Ein Dropdown-Listenfeld mit Medientypen und dem Beispielwert und -schema.
Wenn die Swagger-Seite nicht angezeigt wird, finden Sie weitere Informationen in diesem GitHub-Issue.
Swagger wird verwendet, um hilfreiche Dokumentation und Hilfeseiten für Web-APIs zu generieren. In diesem Tutorial wird Swagger zum Testen der App verwendet. Weitere Informationen zu Swagger finden Sie in ASP.NET Core Web-API-Dokumentation mit Swagger/OpenAPI.
Kopieren Sie die Anforderungs-URL, und fügen Sie sie im Browser ein: https://localhost:<port>/weatherforecast
Der zurückgegebene JSON-Code sieht in etwa wie das folgende Beispiel aus:
[
{
"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"
}
]
Hinzufügen einer Modellklasse
Ein Modell ist eine Gruppe von Klassen, die die Daten darstellen, die die App verwaltet. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Klicken Sie auf Hinzufügen>Neuer Ordner. Geben Sie dem Ordner den Namen
Models
anmelden. - Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoItem, und wählen Sie Hinzufügen aus. - Ersetzen Sie den Vorlagencode durch Folgendes:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Die Id
-Eigenschaft fungiert als eindeutiger Schlüssel in einer relationalen Datenbank.
Modellklassen können überall im Projekt platziert werden, doch gemäß der Konvention wird der Ordner Models
verwendet.
Hinzufügen eines Datenbankkontexts
Der Datenbankkontext ist die Hauptklasse, die die Entity Framework-Funktionen für ein Datenmodell koordiniert. Diese Klasse wird durch Ableiten von der Microsoft.EntityFrameworkCore.DbContext-Klasse erstellt.
- Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoContext, und klicken Sie auf Hinzufügen.
Geben Sie den folgenden Code ein:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Registrieren des Datenbankkontexts
In ASP.NET Core müssen Dienste wie der Datenbankkontext mit dem Container Abhängigkeitsinjektion registriert werden. Der Container stellt den Dienst für Controller bereit.
Aktualisieren Sie Program.cs
mit dem folgenden hervorgehobenen 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();
Der vorangehende Code:
- Fügt
using
-Richtlinien hinzu. - Fügt dem Abhängigkeitscontainer den Datenbankkontext hinzu
- Gibt an, dass der Datenbankkontext eine In-Memory Database verwendet
Erstellen eines Controllergerüsts
Klicken Sie mit der rechten Maustaste auf den Ordner
Controllers
.Wählen Sie Hinzufügen>New Scaffolded Item aus.
Klicken Sie auf API-Controller mit Aktionen unter Verwendung von Entity Framework und dann auf Hinzufügen.
Führen Sie im Dialogfeld API-Controller mit Aktionen unter Verwendung von Entity Framework folgende Schritte aus:
- Wählen Sie in der Modellklasse das Element TodoItem (TodoApi.Models) aus.
- Wählen Sie in der Datenkontextklasse das Element TodoContext (TodoApi.Models) aus.
- Wählen Sie Hinzufügen aus.
Wenn beim Gerüstbauvorgang ein Fehler auftritt, wählen Sie Hinzufügen aus, um ein zweites Mal den Gerüstbau zu versuchen.
Der generierte Code hat folgende Auswirkungen:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen über bestimmte Verhaltensweisen, die das Attribut aktivieren, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet die Abhängigkeitsinjektion, um den Datenbankkontext (
TodoContext
) dem Controller hinzuzufügen. Der Datenbankkontext wird in den einzelnen CRUD-Methoden im Controller verwendet.
Die ASP.NET Core-Vorlagen für:
- Controller mit Ansichten enthalten
[action]
in der Routenvorlage. - API-Controller enthalten keine
[action]
in der Routenvorlage.
Wenn sich das [action]
-Token nicht in der Routenvorlage befindet, ist der Aktionsname (Methodenname) nicht im Endpunkt enthalten. Dies bedeutet, dass der zugehörige Methodenname der Aktion nicht in der übereinstimmenden Route verwendet wird.
Aktualisieren der PostTodoItem-Erstellungsmethode
Aktualisieren Sie die Rückgabeanweisung in PostTodoItem
mit dem 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);
}
Der oben stehende Code ist eine HTTP POST
-Methode, wie durch das [HttpPost]
-Attribut angegeben. Die Methode ruft den Wert von TodoItem
aus dem Text der HTTP-Anforderung ab.
Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
Die CreatedAtAction-Methode:
- Gibt bei Erfolg den HTTP-Statuscode 201 zurück.
HTTP 201
ist die Standardantwort für eineHTTP POST
-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Der
Location
-Header legt den URI des neu erstellten To-do-Elements fest. Weitere Informationen finden Sie unter 10.2.2 201 Created. - Verweist auf die
GetTodoItem
-Aktion zum Erstellen des URIs desLocation
-Headers. Dasnameof
-Schlüsselwort von C# wird verwendet, um eine Hartcodierung des Aktionsnamens imCreatedAtAction
-Aufruf zu vermeiden.
Testen von PostTodoItem
Drücken Sie STRG+F5, um die App auszuführen.
Wählen Sie im Swagger-Browserfenster POST /api/TodoItems und dann Try it out aus.
Aktualisieren Sie im Eingabefenster Anforderungstext das JSON. Beispiel:
{ "name": "walk dog", "isComplete": true }
Wählen Sie Execute.
Testen des Adressheader-URIs
In der vorstehenden POST zeigt die Swagger-Benutzeroberfläche den Adressheader unter Response Headers an. Beispiel: location: https://localhost:7260/api/TodoItems/1
. Der Adressheader zeigt den URI für die erstellte Ressource an.
Testen des Adressheaders:
Wählen Sie im Swagger-Browserfenster GET /api/TodoItems{id} und dann Try it out aus.
Geben Sie
1
in das Eingabefeldid
ein, und wählen Sie dann Execute aus.
Überblick über die GET-Methoden
Zwei GET-Endpunkte werden implementiert:
GET /api/todoitems
GET /api/todoitems/{id}
Der vorherige Abschnitt veranschaulichte ein Beispiel für die /api/todoitems/{id}
-Route.
Folgen Sie den POST-Anweisungen, um ein weiteres Todo-Element hinzuzufügen, und testen Sie dann die /api/todoitems
-Route mit Swagger.
Diese App verwendet eine In-Memory-Datenbank. Wenn die App angehalten und dann wieder gestartet wird, werden durch die vorherige GET-Anforderung keine Daten zurückgegeben. Wenn keine Daten zurückgegeben werden, senden Sie mit POST Daten an die App.
Routing und URL-Pfade
Das [HttpGet]
-Attribut gibt eine Methode an, die auf eine HTTP GET
-Anforderung antwortet. Der URL-Pfad für jede Methode wird wie folgt erstellt:
Beginnen Sie mit der Vorlagenzeichenfolge im
Route
-Attribut des Controllers:[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Ersetzen Sie
[controller]
durch den Namen des Controllers, bei dem es sich standardmäßig um den Namen der Controller-Klasse ohne das Suffix „Controller“ handelt. In diesem Beispiel ist der Klassenname des Controllers „TodoItemsController“. Der Controllername lautet also „TodoItems“. Beim ASP.NET Core-Routing wird die Groß-/Kleinschreibung nicht beachtet.Wenn das
[HttpGet]
-Attribut eine Routenvorlage (z. B.[HttpGet("products")]
) hat, fügen Sie diese an den Pfad an. In diesem Beispiel wird keine Vorlage verwendet. Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
In der folgenden GetTodoItem
-Methode ist "{id}"
eine Platzhaltervariable für den eindeutigen Bezeichner des To-do-Elements. Wenn GetTodoItem
aufgerufen wird, wird der Wert von "{id}"
in der URL der Methode in ihrem Parameter id
bereitgestellt.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Rückgabewerte
Der Rückgabetyp der Methoden GetTodoItems
und GetTodoItem
ist ActionResult<T>-Typ . ASP.NET Core serialisiert automatisch das Objekt in JSON und schreibt den JSON-Code in den Text der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine Ausnahmefehler. Nicht behandelte Ausnahmen werden in 5xx-Fehler übersetzt.
ActionResult
-Rückgabetypen können eine Vielzahl von HTTP-Statuscodes darstellen. Beispielsweise kann GetTodoItem
zwei verschiedene Statuswerte zurückgeben:
- Wenn kein Element mit der angeforderten ID übereinstimmt, gibt die Methode einen NotFound-Fehlercode Status 404 zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
item
löst eineHTTP 200
-Antwort aus.
PutTodoItem-Methode
Untersuchen Sie die 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
ähnelt PostTodoItem
, verwendet allerdings HTTP PUT
. Die Antwort ist 204 (No Content). Gemäß der HTTP-Spezifikation erfordert eine PUT
-Anforderung, dass der Client die gesamte aktualisierte Entität (nicht nur die Änderungen) sendet. Verwenden Sie HTTP PATCH, um Teilupdates zu unterstützen.
Testen der PutTodoItem-Methode
In diesem Beispiel wird eine In-Memory-Datenbank verwendet, die jedes Mal initialisiert werden muss, wenn die App gestartet wird. Es muss ein Element in der Datenbank vorhanden sein, bevor Sie einen PUT-Aufruf durchführen. Rufen Sie vor einem PUT-Aufruf GET auf, um sicherzustellen, dass ein Element in der Datenbank vorhanden ist.
Verwenden Sie in der Swagger-Benutzeroberfläche die PUT-Schaltfläche, um das TodoItem
-Element mit der ID = 1 zu aktualisieren und seinen Namen auf "feed fish"
festzulegen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
DeleteTodoItem-Methode
Untersuchen Sie die 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();
}
Testen der DeleteTodoItem-Methode
Verwenden Sie die Benutzeroberfläche von Swagger, um das TodoItem
-Element mit der ID = 1 zu löschen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
Testen mit anderen Tools
Es gibt viele andere Tools, die zum Testen von Web-APIs verwendet werden können, z. B.:
- Visual Studio-Endpunkte Explorer und HTTP-Dateien
- http-repl
- curl. Swagger verwendet
curl
und zeigt die gesendetencurl
-Befehle an. - Fiddler
Weitere Informationen finden Sie unter
- Minimales API-Tutorial: Testen mit HTTP-Dateien und Endpunkte-Explorer
- Installieren und Testen von APIs mit
http-repl
Vermeiden von Overposting
Derzeit macht die Beispiel-App das gesamte TodoItem
-Objekt verfügbar. In den Produktions-Apps sind die Daten, die eingegeben und mithilfe einer Teilmenge des Modells zurückgegeben werden, in der Regel eingeschränkt. Hierfür gibt es mehrere Gründe, wobei die Sicherheit einer der Hauptgründe ist. Die Teilmenge eines Modells wird üblicherweise als Datenübertragungsobjekt (DTO, Data Transfer Object), Eingabemodell oder Anzeigemodell bezeichnet. In diesem Tutorial wird DTO verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Ausblenden von Eigenschaften, die Clients nicht anzeigen sollen
- Auslassen einiger Eigenschaften, um die Nutzlast zu verringern
- Vereinfachen von Objektgraphen, die geschachtelte Objekte enthalten Vereinfachte Objektgraphen können für Clients zweckmäßiger sein.
Um den DTO-Ansatz zu veranschaulichen, aktualisieren Sie die TodoItem
-Klasse, sodass sie ein geheimes Feld einschließt:
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; }
}
}
Das geheime Feld muss in dieser App ausgeblendet werden, eine administrative App kann es jedoch verfügbar machen.
Vergewissern Sie sich, dass Sie das geheime Feld veröffentlichen und abrufen können.
Erstellen Sie ein DTO-Modell:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Aktualisieren Sie TodoItemsController
, sodass TodoItemDTO
verwendet wird:
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
};
}
Vergewissern Sie sich, dass Sie das geheime Feld weder veröffentlichen noch abrufen können.
Aufrufen der Web-API mit JavaScript
Mehr dazu finden Sie im -Tutorial: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Sehen Sie sich das Video: Einsteigerreihe: Web-APIs an.
Zuverlässige Web-App-Muster
Einen Leitfaden zum Erstellen einer modernen, zuverlässigen, leistungsfähigen, testbaren, kosteneffizienten und skalierbaren ASP.NET Core-App finden Sie in den YouTube-Videos und im Artikel zum zuverlässigen Web-App-Muster für .NET – ganz gleich, ob Sie eine App von Grund auf neu erstellen oder umgestalten möchten.
Hinzufügen der Authentifizierungsunterstützung zu einer Web-API
ASP.NET Core Identity fügt Benutzeroberflächen-Anmeldefunktionen zu ASP.NET Core-Web-Apps hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:
- Authentifizierung als Dienst
- Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
- Zugriffssteuerung für APIs
- Federation Gateway
Wichtig
Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.
Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).
Veröffentlichen in Azure
Weitere Informationen zur Bereistellung in Azure finden Sie unter Schnellstart: Bereitstellen einer ASP.NET-Web-App.
Zusätzliche Ressourcen
Sie können den Beispielcode für dieses Tutorial anzeigen oder herunterladen. Informationen zum Herunterladen finden Sie hier.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Tutorial: Erstellen einer minimalen API mit ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Razor Pages mit Entity Framework Core in ASP.NET Core:Tutorial 1 von 8
- Routing zu Controlleraktionen in ASP.NET Core
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps in Azure App Service
- Hosten und Bereitstellen von ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core
In diesem Tutorial lernen Sie die Grundlagen der Erstellung einer controllerbasierten Web-API, die eine Datenbank verwendet. Ein anderer Ansatz zum Erstellen von APIs in ASP.NET Core besteht in der Erstellung von minimalen APIs. Hilfe bei der Entscheidung zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Anleitungen zum Erstellen einer minimalen API finden Sie im Tutorial: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
API | Beschreibung | Anforderungstext | Antworttext |
---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | Keine | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | Keine | To-do-Element |
POST /api/todoitems |
Neues Element hinzufügen | To-do-Element | To-do-Element |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | To-do-Element | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit der Workload ASP.NET und Webentwicklung
Erstellen eines Webprojekts
- Klicken Sie im Menü Datei auf Neu>Projekt.
- Geben Sie Web-API in das Suchfeld ein.
- Wählen Sie die ASP.NET Core-Web-API-Vorlage aus, und klicken Sie auf Weiter.
- Geben Sie im Dialogfeld Neues Projekt konfigurieren dem Projekt den Namen TodoApi, und wählen Sie dann Weiter aus.
- Im Dialogfeld Zusätzliche Informationen:
- Bestätigen Sie, dass das Framework auf .NET 8.0 (Langfristiger Support) festgelegt ist.
- Vergewissern Sie sich, dass das Kontrollkästchen Controller verwenden (zur Verwendung minimaler APIs deaktivieren) aktiviert ist.
- Vergewissern Sie sich, dass das Kontrollkästchen OpenAPI-Unterstützung aktivieren aktiviert ist.
- Klicken Sie auf Erstellen.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Klicken Sie im Menü Extras auf NuGet-Paket-Manager > NuGet-Pakete für Projektmappe verwalten.
- Wählen Sie die Registerkarte Durchsuchen aus.
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
aus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Hinweis
Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Testen des Projekts
Die Projektvorlage erstellt eine WeatherForecast
-API mit Unterstützung für Swagger.
Drücken Sie STRG+F5, um die Ausführung ohne den Debugger zu starten.
Visual Studio zeigt das folgende Dialogfeld an, wenn ein Projekt noch nicht für die Verwendung von SSL konfiguriert ist:
Wählen Sie Ja aus, wenn Sie dem IIS Express-SLL-Zertifikat vertrauen möchten.
Das folgende Dialogfeld wird angezeigt:
Klicken Sie auf Ja, wenn Sie zustimmen möchten, dass das Entwicklungszertifikat vertrauenswürdig ist.
Informationen dazu, wie Sie dem Firefox-Browser vertrauen, finden Sie unter Firefox-Zertifikatfehler SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio startet einen Standardbrowser und navigiert zu https://localhost:<port>/swagger/index.html
, wobei es sich bei <port>
um eine zufällig ausgewählte Portnummer handelt.
Die Swagger-Seite /swagger/index.html
wird angezeigt. Wählen Sie GET>Tryit out>Execute (GET > Testen> Ausführen) aus. Die Seite zeigt Folgendes an:
- Der Curl-Befehl, zum Testen der WeatherForecast-API.
- Die URL zum Testen der WeatherForecast-API.
- Der Antwortcode, der Text und die Header.
- Ein Dropdown-Listenfeld mit Medientypen und dem Beispielwert und -schema.
Wenn die Swagger-Seite nicht angezeigt wird, finden Sie weitere Informationen in diesem GitHub-Issue.
Swagger wird verwendet, um hilfreiche Dokumentation und Hilfeseiten für Web-APIs zu generieren. In diesem Tutorial wird Swagger zum Testen der App verwendet. Weitere Informationen zu Swagger finden Sie in ASP.NET Core Web-API-Dokumentation mit Swagger/OpenAPI.
Kopieren Sie die Anforderungs-URL, und fügen Sie sie im Browser ein: https://localhost:<port>/weatherforecast
Der zurückgegebene JSON-Code sieht in etwa wie das folgende Beispiel aus:
[
{
"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"
}
]
Hinzufügen einer Modellklasse
Ein Modell ist eine Gruppe von Klassen, die die Daten darstellen, die die App verwaltet. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Klicken Sie auf Hinzufügen>Neuer Ordner. Geben Sie dem Ordner den Namen
Models
anmelden. - Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoItem, und wählen Sie Hinzufügen aus. - Ersetzen Sie den Vorlagencode durch Folgendes:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Die Id
-Eigenschaft fungiert als eindeutiger Schlüssel in einer relationalen Datenbank.
Modellklassen können überall im Projekt platziert werden, doch gemäß der Konvention wird der Ordner Models
verwendet.
Hinzufügen eines Datenbankkontexts
Der Datenbankkontext ist die Hauptklasse, die die Entity Framework-Funktionen für ein Datenmodell koordiniert. Diese Klasse wird durch Ableiten von der Microsoft.EntityFrameworkCore.DbContext-Klasse erstellt.
- Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoContext, und klicken Sie auf Hinzufügen.
Geben Sie den folgenden Code ein:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Registrieren des Datenbankkontexts
In ASP.NET Core müssen Dienste wie der Datenbankkontext mit dem Container Abhängigkeitsinjektion registriert werden. Der Container stellt den Dienst für Controller bereit.
Aktualisieren Sie Program.cs
mit dem folgenden hervorgehobenen 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();
Der vorangehende Code:
- Fügt
using
-Richtlinien hinzu. - Fügt dem Abhängigkeitscontainer den Datenbankkontext hinzu
- Gibt an, dass der Datenbankkontext eine In-Memory Database verwendet
Erstellen eines Controllergerüsts
Klicken Sie mit der rechten Maustaste auf den Ordner
Controllers
.Wählen Sie Hinzufügen>New Scaffolded Item aus.
Klicken Sie auf API-Controller mit Aktionen unter Verwendung von Entity Framework und dann auf Hinzufügen.
Führen Sie im Dialogfeld API-Controller mit Aktionen unter Verwendung von Entity Framework folgende Schritte aus:
- Wählen Sie in der Modellklasse das Element TodoItem (TodoApi.Models) aus.
- Wählen Sie in der Datenkontextklasse das Element TodoContext (TodoApi.Models) aus.
- Wählen Sie Hinzufügen aus.
Wenn beim Gerüstbauvorgang ein Fehler auftritt, wählen Sie Hinzufügen aus, um ein zweites Mal den Gerüstbau zu versuchen.
Der generierte Code hat folgende Auswirkungen:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen über bestimmte Verhaltensweisen, die das Attribut aktivieren, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet die Abhängigkeitsinjektion, um den Datenbankkontext (
TodoContext
) dem Controller hinzuzufügen. Der Datenbankkontext wird in den einzelnen CRUD-Methoden im Controller verwendet.
Die ASP.NET Core-Vorlagen für:
- Controller mit Ansichten enthalten
[action]
in der Routenvorlage. - API-Controller enthalten keine
[action]
in der Routenvorlage.
Wenn sich das [action]
-Token nicht in der Routenvorlage befindet, ist der Aktionsname (Methodenname) nicht im Endpunkt enthalten. Dies bedeutet, dass der zugehörige Methodenname der Aktion nicht in der übereinstimmenden Route verwendet wird.
Aktualisieren der PostTodoItem-Erstellungsmethode
Aktualisieren Sie die Rückgabeanweisung in PostTodoItem
mit dem 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);
}
Der oben stehende Code ist eine HTTP POST
-Methode, wie durch das [HttpPost]
-Attribut angegeben. Die Methode ruft den Wert von TodoItem
aus dem Text der HTTP-Anforderung ab.
Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
Die CreatedAtAction-Methode:
- Gibt bei Erfolg den HTTP-Statuscode 201 zurück.
HTTP 201
ist die Standardantwort für eineHTTP POST
-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Der
Location
-Header legt den URI des neu erstellten To-do-Elements fest. Weitere Informationen finden Sie unter 10.2.2 201 Created. - Verweist auf die
GetTodoItem
-Aktion zum Erstellen des URIs desLocation
-Headers. Dasnameof
-Schlüsselwort von C# wird verwendet, um eine Hartcodierung des Aktionsnamens imCreatedAtAction
-Aufruf zu vermeiden.
Testen von PostTodoItem
Drücken Sie STRG+F5, um die App auszuführen.
Wählen Sie im Swagger-Browserfenster POST /api/TodoItems und dann Try it out aus.
Aktualisieren Sie im Eingabefenster Anforderungstext das JSON. Beispiel:
{ "name": "walk dog", "isComplete": true }
Wählen Sie Execute.
Testen des Adressheader-URIs
In der vorstehenden POST zeigt die Swagger-Benutzeroberfläche den Adressheader unter Response Headers an. Beispiel: location: https://localhost:7260/api/TodoItems/1
. Der Adressheader zeigt den URI für die erstellte Ressource an.
Testen des Adressheaders:
Wählen Sie im Swagger-Browserfenster GET /api/TodoItems{id} und dann Try it out aus.
Geben Sie
1
in das Eingabefeldid
ein, und wählen Sie dann Execute aus.
Überblick über die GET-Methoden
Zwei GET-Endpunkte werden implementiert:
GET /api/todoitems
GET /api/todoitems/{id}
Der vorherige Abschnitt veranschaulichte ein Beispiel für die /api/todoitems/{id}
-Route.
Folgen Sie den POST-Anweisungen, um ein weiteres Todo-Element hinzuzufügen, und testen Sie dann die /api/todoitems
-Route mit Swagger.
Diese App verwendet eine In-Memory-Datenbank. Wenn die App angehalten und dann wieder gestartet wird, werden durch die vorherige GET-Anforderung keine Daten zurückgegeben. Wenn keine Daten zurückgegeben werden, senden Sie mit POST Daten an die App.
Routing und URL-Pfade
Das [HttpGet]
-Attribut gibt eine Methode an, die auf eine HTTP GET
-Anforderung antwortet. Der URL-Pfad für jede Methode wird wie folgt erstellt:
Beginnen Sie mit der Vorlagenzeichenfolge im
Route
-Attribut des Controllers:[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Ersetzen Sie
[controller]
durch den Namen des Controllers, bei dem es sich standardmäßig um den Namen der Controller-Klasse ohne das Suffix „Controller“ handelt. In diesem Beispiel ist der Klassenname des Controllers „TodoItemsController“. Der Controllername lautet also „TodoItems“. Beim ASP.NET Core-Routing wird die Groß-/Kleinschreibung nicht beachtet.Wenn das
[HttpGet]
-Attribut eine Routenvorlage (z. B.[HttpGet("products")]
) hat, fügen Sie diese an den Pfad an. In diesem Beispiel wird keine Vorlage verwendet. Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
In der folgenden GetTodoItem
-Methode ist "{id}"
eine Platzhaltervariable für den eindeutigen Bezeichner des To-do-Elements. Wenn GetTodoItem
aufgerufen wird, wird der Wert von "{id}"
in der URL der Methode in ihrem Parameter id
bereitgestellt.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Rückgabewerte
Der Rückgabetyp der Methoden GetTodoItems
und GetTodoItem
ist ActionResult<T>-Typ . ASP.NET Core serialisiert automatisch das Objekt in JSON und schreibt den JSON-Code in den Text der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine Ausnahmefehler. Nicht behandelte Ausnahmen werden in 5xx-Fehler übersetzt.
ActionResult
-Rückgabetypen können eine Vielzahl von HTTP-Statuscodes darstellen. Beispielsweise kann GetTodoItem
zwei verschiedene Statuswerte zurückgeben:
- Wenn kein Element mit der angeforderten ID übereinstimmt, gibt die Methode einen NotFound-Fehlercode Status 404 zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
item
löst eineHTTP 200
-Antwort aus.
PutTodoItem-Methode
Untersuchen Sie die 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
ähnelt PostTodoItem
, verwendet allerdings HTTP PUT
. Die Antwort ist 204 (No Content). Gemäß der HTTP-Spezifikation erfordert eine PUT
-Anforderung, dass der Client die gesamte aktualisierte Entität (nicht nur die Änderungen) sendet. Verwenden Sie HTTP PATCH, um Teilupdates zu unterstützen.
Testen der PutTodoItem-Methode
In diesem Beispiel wird eine In-Memory-Datenbank verwendet, die jedes Mal initialisiert werden muss, wenn die App gestartet wird. Es muss ein Element in der Datenbank vorhanden sein, bevor Sie einen PUT-Aufruf durchführen. Rufen Sie vor einem PUT-Aufruf GET auf, um sicherzustellen, dass ein Element in der Datenbank vorhanden ist.
Verwenden Sie in der Swagger-Benutzeroberfläche die PUT-Schaltfläche, um das TodoItem
-Element mit der ID = 1 zu aktualisieren und seinen Namen auf "feed fish"
festzulegen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
DeleteTodoItem-Methode
Untersuchen Sie die 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();
}
Testen der DeleteTodoItem-Methode
Verwenden Sie die Benutzeroberfläche von Swagger, um das TodoItem
-Element mit der ID = 1 zu löschen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
Testen mit anderen Tools
Es gibt viele andere Tools, die zum Testen von Web-APIs verwendet werden können, z. B.:
- Visual Studio-Endpunkte Explorer und HTTP-Dateien
- http-repl
- curl. Swagger verwendet
curl
und zeigt die gesendetencurl
-Befehle an. - Fiddler
Weitere Informationen finden Sie unter
- Minimales API-Tutorial: Testen mit HTTP-Dateien und Endpunkte-Explorer
- Installieren und Testen von APIs mit
http-repl
Vermeiden von Overposting
Derzeit macht die Beispiel-App das gesamte TodoItem
-Objekt verfügbar. In den Produktions-Apps sind die Daten, die eingegeben und mithilfe einer Teilmenge des Modells zurückgegeben werden, in der Regel eingeschränkt. Hierfür gibt es mehrere Gründe, wobei die Sicherheit einer der Hauptgründe ist. Die Teilmenge eines Modells wird üblicherweise als Datenübertragungsobjekt (DTO, Data Transfer Object), Eingabemodell oder Anzeigemodell bezeichnet. In diesem Tutorial wird DTO verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Ausblenden von Eigenschaften, die Clients nicht anzeigen sollen
- Auslassen einiger Eigenschaften, um die Nutzlast zu verringern
- Vereinfachen von Objektgraphen, die geschachtelte Objekte enthalten Vereinfachte Objektgraphen können für Clients zweckmäßiger sein.
Um den DTO-Ansatz zu veranschaulichen, aktualisieren Sie die TodoItem
-Klasse, sodass sie ein geheimes Feld einschließt:
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; }
}
}
Das geheime Feld muss in dieser App ausgeblendet werden, eine administrative App kann es jedoch verfügbar machen.
Vergewissern Sie sich, dass Sie das geheime Feld veröffentlichen und abrufen können.
Erstellen Sie ein DTO-Modell:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Aktualisieren Sie TodoItemsController
, sodass TodoItemDTO
verwendet wird:
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
};
}
Vergewissern Sie sich, dass Sie das geheime Feld weder veröffentlichen noch abrufen können.
Aufrufen der Web-API mit JavaScript
Mehr dazu finden Sie im -Tutorial: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Sehen Sie sich das Video: Einsteigerreihe: Web-APIs an.
Zuverlässige Web-App-Muster
Einen Leitfaden zum Erstellen einer modernen, zuverlässigen, leistungsfähigen, testbaren, kosteneffizienten und skalierbaren ASP.NET Core-App finden Sie in den YouTube-Videos und im Artikel zum zuverlässigen Web-App-Muster für .NET – ganz gleich, ob Sie eine App von Grund auf neu erstellen oder umgestalten möchten.
Hinzufügen der Authentifizierungsunterstützung zu einer Web-API
ASP.NET Core Identity fügt Benutzeroberflächen-Anmeldefunktionen zu ASP.NET Core-Web-Apps hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:
- Authentifizierung als Dienst
- Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
- Zugriffssteuerung für APIs
- Federation Gateway
Wichtig
Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.
Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).
Veröffentlichen in Azure
Weitere Informationen zur Bereistellung in Azure finden Sie unter Schnellstart: Bereitstellen einer ASP.NET-Web-App.
Zusätzliche Ressourcen
Sie können den Beispielcode für dieses Tutorial anzeigen oder herunterladen. Informationen zum Herunterladen finden Sie hier.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Tutorial: Erstellen einer minimalen API mit ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Razor Pages mit Entity Framework Core in ASP.NET Core:Tutorial 1 von 8
- Routing zu Controlleraktionen in ASP.NET Core
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps in Azure App Service
- Hosten und Bereitstellen von ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core
In diesem Tutorial lernen Sie die Grundlagen der Erstellung einer controllerbasierten Web-API, die eine Datenbank verwendet. Ein anderer Ansatz zum Erstellen von APIs in ASP.NET Core besteht in der Erstellung von minimalen APIs. Hilfe bei der Entscheidung zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Anleitungen zum Erstellen einer minimalen API finden Sie im Tutorial: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
API | Beschreibung | Anforderungstext | Antworttext |
---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | Keine | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | Keine | To-do-Element |
POST /api/todoitems |
Neues Element hinzufügen | To-do-Element | To-do-Element |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | To-do-Element | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit der Workload ASP.NET und Webentwicklung
Erstellen eines Webprojekts
- Klicken Sie im Menü Datei auf Neu>Projekt.
- Geben Sie Web-API in das Suchfeld ein.
- Wählen Sie die ASP.NET Core-Web-API-Vorlage aus, und klicken Sie auf Weiter.
- Geben Sie im Dialogfeld Neues Projekt konfigurieren dem Projekt den Namen TodoApi, und wählen Sie dann Weiter aus.
- Im Dialogfeld Zusätzliche Informationen:
- Bestätigen Sie, dass das Framework auf .NET 8.0 (Langfristiger Support) festgelegt ist.
- Vergewissern Sie sich, dass das Kontrollkästchen Controller verwenden (zur Verwendung minimaler APIs deaktivieren) aktiviert ist.
- Vergewissern Sie sich, dass das Kontrollkästchen OpenAPI-Unterstützung aktivieren aktiviert ist.
- Klicken Sie auf Erstellen.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Klicken Sie im Menü Extras auf NuGet-Paket-Manager > NuGet-Pakete für Projektmappe verwalten.
- Wählen Sie die Registerkarte Durchsuchen aus.
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
aus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Hinweis
Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Testen des Projekts
Die Projektvorlage erstellt eine WeatherForecast
-API mit Unterstützung für Swagger.
Drücken Sie STRG+F5, um die Ausführung ohne den Debugger zu starten.
Visual Studio zeigt das folgende Dialogfeld an, wenn ein Projekt noch nicht für die Verwendung von SSL konfiguriert ist:
Wählen Sie Ja aus, wenn Sie dem IIS Express-SLL-Zertifikat vertrauen möchten.
Das folgende Dialogfeld wird angezeigt:
Klicken Sie auf Ja, wenn Sie zustimmen möchten, dass das Entwicklungszertifikat vertrauenswürdig ist.
Informationen dazu, wie Sie dem Firefox-Browser vertrauen, finden Sie unter Firefox-Zertifikatfehler SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio startet einen Standardbrowser und navigiert zu https://localhost:<port>/swagger/index.html
, wobei es sich bei <port>
um eine zufällig ausgewählte Portnummer handelt.
Die Swagger-Seite /swagger/index.html
wird angezeigt. Wählen Sie GET>Tryit out>Execute (GET > Testen> Ausführen) aus. Die Seite zeigt Folgendes an:
- Der Curl-Befehl, zum Testen der WeatherForecast-API.
- Die URL zum Testen der WeatherForecast-API.
- Der Antwortcode, der Text und die Header.
- Ein Dropdown-Listenfeld mit Medientypen und dem Beispielwert und -schema.
Wenn die Swagger-Seite nicht angezeigt wird, finden Sie weitere Informationen in diesem GitHub-Issue.
Swagger wird verwendet, um hilfreiche Dokumentation und Hilfeseiten für Web-APIs zu generieren. In diesem Tutorial wird Swagger zum Testen der App verwendet. Weitere Informationen zu Swagger finden Sie in ASP.NET Core Web-API-Dokumentation mit Swagger/OpenAPI.
Kopieren Sie die Anforderungs-URL, und fügen Sie sie im Browser ein: https://localhost:<port>/weatherforecast
Der zurückgegebene JSON-Code sieht in etwa wie das folgende Beispiel aus:
[
{
"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"
}
]
Hinzufügen einer Modellklasse
Ein Modell ist eine Gruppe von Klassen, die die Daten darstellen, die die App verwaltet. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Klicken Sie auf Hinzufügen>Neuer Ordner. Geben Sie dem Ordner den Namen
Models
anmelden. - Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoItem, und wählen Sie Hinzufügen aus. - Ersetzen Sie den Vorlagencode durch Folgendes:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Die Id
-Eigenschaft fungiert als eindeutiger Schlüssel in einer relationalen Datenbank.
Modellklassen können überall im Projekt platziert werden, doch gemäß der Konvention wird der Ordner Models
verwendet.
Hinzufügen eines Datenbankkontexts
Der Datenbankkontext ist die Hauptklasse, die die Entity Framework-Funktionen für ein Datenmodell koordiniert. Diese Klasse wird durch Ableiten von der Microsoft.EntityFrameworkCore.DbContext-Klasse erstellt.
- Klicken Sie mit der rechten Maustaste auf den Ordner
Models
, und wählen Sie Hinzufügen>Klasse aus. Nennen Sie die Klasse TodoContext, und klicken Sie auf Hinzufügen.
Geben Sie den folgenden Code ein:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Registrieren des Datenbankkontexts
In ASP.NET Core müssen Dienste wie der Datenbankkontext mit dem Container Abhängigkeitsinjektion registriert werden. Der Container stellt den Dienst für Controller bereit.
Aktualisieren Sie Program.cs
mit dem folgenden hervorgehobenen 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();
Der vorangehende Code:
- Fügt
using
-Richtlinien hinzu. - Fügt dem Abhängigkeitscontainer den Datenbankkontext hinzu
- Gibt an, dass der Datenbankkontext eine In-Memory Database verwendet
Erstellen eines Controllergerüsts
Klicken Sie mit der rechten Maustaste auf den Ordner
Controllers
.Wählen Sie Hinzufügen>New Scaffolded Item aus.
Klicken Sie auf API-Controller mit Aktionen unter Verwendung von Entity Framework und dann auf Hinzufügen.
Führen Sie im Dialogfeld API-Controller mit Aktionen unter Verwendung von Entity Framework folgende Schritte aus:
- Wählen Sie in der Modellklasse das Element TodoItem (TodoApi.Models) aus.
- Wählen Sie in der Datenkontextklasse das Element TodoContext (TodoApi.Models) aus.
- Wählen Sie Hinzufügen aus.
Wenn beim Gerüstbauvorgang ein Fehler auftritt, wählen Sie Hinzufügen aus, um ein zweites Mal den Gerüstbau zu versuchen.
Der generierte Code hat folgende Auswirkungen:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen über bestimmte Verhaltensweisen, die das Attribut aktivieren, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet die Abhängigkeitsinjektion, um den Datenbankkontext (
TodoContext
) dem Controller hinzuzufügen. Der Datenbankkontext wird in den einzelnen CRUD-Methoden im Controller verwendet.
Die ASP.NET Core-Vorlagen für:
- Controller mit Ansichten enthalten
[action]
in der Routenvorlage. - API-Controller enthalten keine
[action]
in der Routenvorlage.
Wenn sich das [action]
-Token nicht in der Routenvorlage befindet, ist der Aktionsname (Methodenname) nicht im Endpunkt enthalten. Dies bedeutet, dass der zugehörige Methodenname der Aktion nicht in der übereinstimmenden Route verwendet wird.
Aktualisieren der PostTodoItem-Erstellungsmethode
Aktualisieren Sie die Rückgabeanweisung in PostTodoItem
mit dem 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);
}
Der oben stehende Code ist eine HTTP POST
-Methode, wie durch das [HttpPost]
-Attribut angegeben. Die Methode ruft den Wert von TodoItem
aus dem Text der HTTP-Anforderung ab.
Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
Die CreatedAtAction-Methode:
- Gibt bei Erfolg den HTTP-Statuscode 201 zurück.
HTTP 201
ist die Standardantwort für eineHTTP POST
-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Der
Location
-Header legt den URI des neu erstellten To-do-Elements fest. Weitere Informationen finden Sie unter 10.2.2 201 Created. - Verweist auf die
GetTodoItem
-Aktion zum Erstellen des URIs desLocation
-Headers. Dasnameof
-Schlüsselwort von C# wird verwendet, um eine Hartcodierung des Aktionsnamens imCreatedAtAction
-Aufruf zu vermeiden.
Testen von PostTodoItem
Drücken Sie STRG+F5, um die App auszuführen.
Wählen Sie im Swagger-Browserfenster POST /api/TodoItems und dann Try it out aus.
Aktualisieren Sie im Eingabefenster Anforderungstext das JSON. Beispiel:
{ "name": "walk dog", "isComplete": true }
Wählen Sie Execute.
Testen des Adressheader-URIs
In der vorstehenden POST zeigt die Swagger-Benutzeroberfläche den Adressheader unter Response Headers an. Beispiel: location: https://localhost:7260/api/TodoItems/1
. Der Adressheader zeigt den URI für die erstellte Ressource an.
Testen des Adressheaders:
Wählen Sie im Swagger-Browserfenster GET /api/TodoItems{id} und dann Try it out aus.
Geben Sie
1
in das Eingabefeldid
ein, und wählen Sie dann Execute aus.
Überblick über die GET-Methoden
Zwei GET-Endpunkte werden implementiert:
GET /api/todoitems
GET /api/todoitems/{id}
Der vorherige Abschnitt veranschaulichte ein Beispiel für die /api/todoitems/{id}
-Route.
Folgen Sie den POST-Anweisungen, um ein weiteres Todo-Element hinzuzufügen, und testen Sie dann die /api/todoitems
-Route mit Swagger.
Diese App verwendet eine In-Memory-Datenbank. Wenn die App angehalten und dann wieder gestartet wird, werden durch die vorherige GET-Anforderung keine Daten zurückgegeben. Wenn keine Daten zurückgegeben werden, senden Sie mit POST Daten an die App.
Routing und URL-Pfade
Das [HttpGet]
-Attribut gibt eine Methode an, die auf eine HTTP GET
-Anforderung antwortet. Der URL-Pfad für jede Methode wird wie folgt erstellt:
Beginnen Sie mit der Vorlagenzeichenfolge im
Route
-Attribut des Controllers:[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Ersetzen Sie
[controller]
durch den Namen des Controllers, bei dem es sich standardmäßig um den Namen der Controller-Klasse ohne das Suffix „Controller“ handelt. In diesem Beispiel ist der Klassenname des Controllers „TodoItemsController“. Der Controllername lautet also „TodoItems“. Beim ASP.NET Core-Routing wird die Groß-/Kleinschreibung nicht beachtet.Wenn das
[HttpGet]
-Attribut eine Routenvorlage (z. B.[HttpGet("products")]
) hat, fügen Sie diese an den Pfad an. In diesem Beispiel wird keine Vorlage verwendet. Weitere Informationen finden Sie unter Attributrouting mit Http[Verb]-Attributen.
In der folgenden GetTodoItem
-Methode ist "{id}"
eine Platzhaltervariable für den eindeutigen Bezeichner des To-do-Elements. Wenn GetTodoItem
aufgerufen wird, wird der Wert von "{id}"
in der URL der Methode in ihrem Parameter id
bereitgestellt.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Rückgabewerte
Der Rückgabetyp der Methoden GetTodoItems
und GetTodoItem
ist ActionResult<T>-Typ . ASP.NET Core serialisiert automatisch das Objekt in JSON und schreibt den JSON-Code in den Text der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine Ausnahmefehler. Nicht behandelte Ausnahmen werden in 5xx-Fehler übersetzt.
ActionResult
-Rückgabetypen können eine Vielzahl von HTTP-Statuscodes darstellen. Beispielsweise kann GetTodoItem
zwei verschiedene Statuswerte zurückgeben:
- Wenn kein Element mit der angeforderten ID übereinstimmt, gibt die Methode einen NotFound-Fehlercode Status 404 zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
item
löst eineHTTP 200
-Antwort aus.
PutTodoItem-Methode
Untersuchen Sie die 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
ähnelt PostTodoItem
, verwendet allerdings HTTP PUT
. Die Antwort ist 204 (No Content). Gemäß der HTTP-Spezifikation erfordert eine PUT
-Anforderung, dass der Client die gesamte aktualisierte Entität (nicht nur die Änderungen) sendet. Verwenden Sie HTTP PATCH, um Teilupdates zu unterstützen.
Testen der PutTodoItem-Methode
In diesem Beispiel wird eine In-Memory-Datenbank verwendet, die jedes Mal initialisiert werden muss, wenn die App gestartet wird. Es muss ein Element in der Datenbank vorhanden sein, bevor Sie einen PUT-Aufruf durchführen. Rufen Sie vor einem PUT-Aufruf GET auf, um sicherzustellen, dass ein Element in der Datenbank vorhanden ist.
Verwenden Sie in der Swagger-Benutzeroberfläche die PUT-Schaltfläche, um das TodoItem
-Element mit der ID = 1 zu aktualisieren und seinen Namen auf "feed fish"
festzulegen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
DeleteTodoItem-Methode
Untersuchen Sie die 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();
}
Testen der DeleteTodoItem-Methode
Verwenden Sie die Benutzeroberfläche von Swagger, um das TodoItem
-Element mit der ID = 1 zu löschen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
Testen mit anderen Tools
Es gibt viele andere Tools, die zum Testen von Web-APIs verwendet werden können, z. B.:
- Visual Studio-Endpunkte Explorer und HTTP-Dateien
- http-repl
- curl. Swagger verwendet
curl
und zeigt die gesendetencurl
-Befehle an. - Fiddler
Weitere Informationen finden Sie unter
- Minimales API-Tutorial: Testen mit HTTP-Dateien und Endpunkte-Explorer
- Installieren und Testen von APIs mit
http-repl
Vermeiden von Overposting
Derzeit macht die Beispiel-App das gesamte TodoItem
-Objekt verfügbar. In den Produktions-Apps sind die Daten, die eingegeben und mithilfe einer Teilmenge des Modells zurückgegeben werden, in der Regel eingeschränkt. Hierfür gibt es mehrere Gründe, wobei die Sicherheit einer der Hauptgründe ist. Die Teilmenge eines Modells wird üblicherweise als Datenübertragungsobjekt (DTO, Data Transfer Object), Eingabemodell oder Anzeigemodell bezeichnet. In diesem Tutorial wird DTO verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Ausblenden von Eigenschaften, die Clients nicht anzeigen sollen
- Auslassen einiger Eigenschaften, um die Nutzlast zu verringern
- Vereinfachen von Objektgraphen, die geschachtelte Objekte enthalten Vereinfachte Objektgraphen können für Clients zweckmäßiger sein.
Um den DTO-Ansatz zu veranschaulichen, aktualisieren Sie die TodoItem
-Klasse, sodass sie ein geheimes Feld einschließt:
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; }
}
}
Das geheime Feld muss in dieser App ausgeblendet werden, eine administrative App kann es jedoch verfügbar machen.
Vergewissern Sie sich, dass Sie das geheime Feld veröffentlichen und abrufen können.
Erstellen Sie ein DTO-Modell:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Aktualisieren Sie TodoItemsController
, sodass TodoItemDTO
verwendet wird:
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
};
}
Vergewissern Sie sich, dass Sie das geheime Feld weder veröffentlichen noch abrufen können.
Aufrufen der Web-API mit JavaScript
Mehr dazu finden Sie im -Tutorial: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Sehen Sie sich das Video: Einsteigerreihe: Web-APIs an.
Zuverlässige Web-App-Muster
Einen Leitfaden zum Erstellen einer modernen, zuverlässigen, leistungsfähigen, testbaren, kosteneffizienten und skalierbaren ASP.NET Core-App finden Sie in den YouTube-Videos und im Artikel zum zuverlässigen Web-App-Muster für .NET – ganz gleich, ob Sie eine App von Grund auf neu erstellen oder umgestalten möchten.
Hinzufügen der Authentifizierungsunterstützung zu einer Web-API
ASP.NET Core Identity fügt Benutzeroberflächen-Anmeldefunktionen zu ASP.NET Core-Web-Apps hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:
- Authentifizierung als Dienst
- Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
- Zugriffssteuerung für APIs
- Federation Gateway
Wichtig
Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.
Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).
Veröffentlichen in Azure
Weitere Informationen zur Bereistellung in Azure finden Sie unter Schnellstart: Bereitstellen einer ASP.NET-Web-App.
Zusätzliche Ressourcen
Sie können den Beispielcode für dieses Tutorial anzeigen oder herunterladen. Informationen zum Herunterladen finden Sie hier.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Tutorial: Erstellen einer minimalen API mit ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Razor Pages mit Entity Framework Core in ASP.NET Core:Tutorial 1 von 8
- Routing zu Controlleraktionen in ASP.NET Core
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps in Azure App Service
- Hosten und Bereitstellen von ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core