Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-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.
Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Von Tim Deschryver und Rick Anderson
In diesem Tutorial lernen Sie die Grundlagen der Erstellung einer controllerbasierten Web-API, die eine Datenbank verwendet. Ein weiterer Ansatz zum Erstellen von APIs in ASP.NET Core besteht darin, minimale APIs zu erstellen. Hilfe bei der Auswahl zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Ein Lernprogramm zum Erstellen einer minimalen API finden Sie im Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
Programmierschnittstelle (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 | Aufgabenpunkt |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenpunkt | Aufgabenpunkt |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenpunkt | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit ASP.NET - und Webentwicklungsworkload .
Erstellen eines Web-API-Projekts
- Wählen Sie im Menü "Datei" die Option "Neues Projekt"> aus.
- Geben Sie die Web-API in das Suchfeld ein.
- Wählen Sie die Vorlage ASP.NET Core Web API aus , und wählen Sie "Weiter" aus.
- Benennen Sie im Dialogfeld "Neues Projekt konfigurieren" das Projekt "TodoApi ", und wählen Sie "Weiter" aus.
- Im Dialogfeld "Zusätzliche Informationen ":
- Vergewissern Sie sich, dass das Framework.NET 9.0 (Standard Term Support) ist.
- Bestätigen Sie, dass das Kontrollkästchen für die OpenAPI-Unterstützung aktiviert ist.
- Vergewissern Sie sich, dass das Kontrollkästchen für "Controller verwenden" aktiviert ist (deaktivieren Sie die Verwendung minimaler APIs ).
- Wählen Sie "Erstellen" aus.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Wählen Sie im Menü "Extras " die Option "NuGet-Paket-Manager > Verwalten von NuGet-Paketen für Lösung" aus.
- Wählen Sie die Registerkarte " Durchsuchen" aus .
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
dann aus. - Aktivieren Sie das Kontrollkästchen "Projekt " im rechten Bereich, und wählen Sie dann "Installieren" aus.
Hinweis
Anleitungen zum Hinzufügen von Paketen zu .NET-Apps finden Sie in den Artikeln unter "Installieren und Verwalten von Paketen" im Workflow "Paketverbrauch" (NuGet-Dokumentation). Bestätigen Sie die richtigen Paketversionen bei NuGet.org.
Projekt ausführen
Die Projektvorlage erstellt eine WeatherForecast
API mit Unterstützung für OpenAPI.
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-SSL-Zertifikat vertrauen.
Das folgende Dialogfeld wird angezeigt:
Wählen Sie "Ja " aus, wenn Sie dem Entwicklungszertifikat vertrauen möchten.
Informationen zum Vertrauen in den Firefox-Browser finden Sie unter Firefox SEC_ERROR_INADEQUATE_KEY_USAGE-Zertifikatfehler.
Visual Studio startet ein Terminalfenster und zeigt die URL der ausgeführten App an. Die API wird bei https://localhost:<port>
gehostet, wobei <port>
eine zufällig ausgewählte Portnummer ist, die bei der Projekterstellung festgelegt ist.
...
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.
...
Strg+Klicken Sie in der Ausgabe auf die HTTPS-URL, um die Web-App in einem Browser zu testen. Es ist kein Endpunkt vorhanden, https://localhost:<port>
daher gibt der Browser HTTP 404 nicht gefunden zurück.
Fügen Sie /weatherforecast
an die URL an, um die WeatherForecast-API zu testen.
Der Browser zeigt JSON ähnlich wie im folgenden Beispiel an:
[
{
"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"
}
]
Testen des Projekts
In diesem Lernprogramm werden Endpunkt-Explorer- und HTTP-Dateien verwendet, um die API zu testen.
Hinzufügen einer Modellklasse
Ein Modell ist eine Reihe von Klassen, die die von der App verwalteten Daten darstellen. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Wählen Sie "Neuen Ordner>" aus. Geben Sie dem Ordner den Namen
Models
. - Klicken Sie mit der rechten Maustaste auf den
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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-Funktionalität 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
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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 im Container der Dependency Injection (DI) 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.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();
Der vorangehende Code:
- Fügt
using
-Richtlinien hinzu. - Fügt dem DI-Container 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.
Wählen Sie API Controller mit Aktionen, mithilfe von Entity Framework, und wählen Sie dann "Hinzufügen" aus.
Im Dialogfenster "API-Controller mit Aktionen hinzufügen, unter Verwendung des Entitätsframeworks" :
- Wählen Sie TodoItem (TodoApi.Models) in der Model-Klasse aus.
- Wählen Sie TodoContext (TodoApi.Models) in der Data-Kontextklasse aus.
- Wählen Sie "Hinzufügen" aus.
Wenn der Gerüstvorgang fehlschlägt, wählen Sie "Hinzufügen" aus, um das Gerüst ein zweites Mal zu versuchen.
In diesem Schritt werden dem Projekt die Microsoft.VisualStudio.Web.CodeGeneration.Design
und Microsoft.EntityFrameworkCore.Tools
NuGet-Pakete hinzugefügt.
Diese Pakete sind für das Gerüst erforderlich.
Der generierte Code:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen zu bestimmten Verhaltensweisen, die das Attribut ermöglicht, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet DI, um den Datenbankkontext (
TodoContext
) in den Controller zu injizieren. Der Datenbankkontext wird in den einzelnen CRUD-Methoden des Controllers 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 das [action]
Token nicht in der Routenvorlage enthalten ist, 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
, um den nameof-Operator zu verwenden.
[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 erfolgreicher Ausführung einen HTTP 201-Statuscode 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. Die
Location
Kopfzeile gibt den URI des neu erstellten to-do Elements an. Weitere Informationen finden Sie unter 10.2.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
Wählen Sie ">Windows-Endpunkte-Explorer> anzeigen" aus.
Klicken Sie mit der rechten Maustaste auf den POST-Endpunkt , und wählen Sie "Anforderung generieren" aus.
Im Projektordner mit dem Namen
TodoApi.http
wird eine neue Datei erstellt, deren Inhalt dem folgenden Beispiel ähnelt:@TodoApi_HostAddress = https://localhost:49738 POST {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { //TodoItem } ###
- Die erste Zeile erstellt eine Variable, die für alle Endpunkte verwendet wird.
- Die nächste Zeile definiert eine POST-Anforderung.
- Die Zeilen nach der POST-Anforderungszeile definieren die Kopfzeilen und einen Platzhalter für den Anforderungstext.
- Die Zeile mit dem dreifachen Hashtag (
###
) ist ein Anforderungstrennzeichen: Was danach kommt, gilt für eine andere Anforderung.
Die POST-Anforderung erwartet eine
TodoItem
. Um den Todo zu definieren, ersetzen Sie den//TodoItem
Kommentar durch den folgenden JSON-Code:{ "name": "walk dog", "isComplete": true }
Die Datei TodoApi.http sollte nun wie im folgenden Beispiel aussehen, aber mit Ihrer Portnummer:
@TodoApi_HostAddress = https://localhost:7260 Post {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { "name": "walk dog", "isComplete": true } ###
Führen Sie die App aus.
Wählen Sie den Link " Anfrage senden " aus, der sich über der Anforderungszeile
POST
befindet.Die POST-Anforderung wird an die App gesendet, und die Antwort wird im Antwortbereich angezeigt.
Testen des Adressheader-URIs
Testen Sie die App, indem Sie die GET
Endpunkte aus einem Browser oder mithilfe des Endpunkt-Explorers aufrufen. Die folgenden Schritte gelten für Endpunkt-Explorer.
Klicken Sie im Endpunkt-Explorer mit der rechten Maustaste auf den ersten GET-Endpunkt , und wählen Sie "Anforderung generieren" aus.
Der folgende Inhalt wird der datei
TodoApi.http
hinzugefügt:GET {{TodoApi_HostAddress}}/api/todoitems ###
Wählen Sie den Link " Anforderung senden " aus, der sich oberhalb der neuen
GET
Anforderungszeile befindet.Die GET-Anforderung wird an die App gesendet und die Antwort wird im Antwortbereich angezeigt.
Der Antwortkörper ähnelt dem folgenden JSON.
[ { "id": 1, "name": "walk dog", "isComplete": true } ]
Klicken Sie im Endpunkt-Explorer mit der rechten Maustaste auf den
/api/todoitems/{id}
GET-Endpunkt , und wählen Sie "Anforderung generieren" aus. Der folgende Inhalt wird der dateiTodoApi.http
hinzugefügt:@id=0 GET {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Weisen Sie
{@id}
zu1
(anstelle von0
) zu.Wählen Sie den Link " Anforderung senden" aus, der sich oberhalb der neuen GET-Anforderungszeile befindet.
Die GET-Anforderung wird an die App gesendet und die Antwort wird im Antwortbereich angezeigt.
Der Antwortkörper ähnelt dem folgenden JSON.
{ "id": 1, "name": "walk dog", "isComplete": true }
Ü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 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. Für dieses Beispiel ist der Controllerklassenname TodoItemsController, sodass der Controllername "TodoItems" lautet. ASP.NET Core Routing ist nicht groß-/kleinschreibungssensitiv.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 Methode in ihrem Parameter "{id}"
der Wert von id
aus der URL 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 GetTodoItems
- und GetTodoItem
-Methoden ist vom ActionResult<T>-Typ. ASP.NET Core serialisiert das Objekt automatisch in JSON und schreibt den JSON-Code in den Textkörper der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine unbehandelten Ausnahmen. 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 den Fehlercode 404 zurückNotFound .
- 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 lautet 204 (Kein Inhalt). 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 die PUT
-Methode, um die TodoItem
mit id = 1 zu aktualisieren und den Namen auf "feed fish"
festzulegen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
Klicken Sie im Endpunkt-Explorer mit der rechten Maustaste auf den PUT-Endpunkt , und wählen Sie "Anforderung generieren" aus.
Der folgende Inhalt wird der datei
TodoApi.http
hinzugefügt:PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}} Content-Type: application/json { //TodoItem } ###
Ersetzen Sie in der PUT-Anforderungszeile
{{id}}
durch1
.Ersetzen Sie den Platzhalter
//TodoItem
durch die folgenden Zeilen:PUT {{TodoApi_HostAddress}}/api/todoitems/1 Content-Type: application/json { "id": 1, "name": "feed fish", "isComplete": false }
Wählen Sie den Link " Anforderung senden " aus, der sich oberhalb der neuen PUT-Anforderungszeile befindet.
Die PUT-Anforderung wird an die App gesendet, und die Antwort wird im Antwortbereich angezeigt. Der Antworttext ist leer, und der Statuscode ist 204.
Die 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 DELETE
-Methode, um die TodoItem
mit der ID = 1 zu löschen. Beachten Sie, dass die Antwort HTTP 204 No Content
lautet.
Klicken Sie im Endpunkt-Explorer mit der rechten Maustaste auf den DELETE-Endpunkt , und wählen Sie "Anforderung generieren" aus.
Eine DELETE-Anforderung wird zu
TodoApi.http
hinzugefügt.Ersetzen Sie
{{id}}
in der DELETE-Anforderungszeile durch1
. Die DELETE-Anforderung sollte wie im folgenden Beispiel aussehen:DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Wählen Sie den Link " Anforderung senden " für die DELETE-Anforderung aus.
Die DELETE-Anforderung wird an die App gesendet, und die Antwort wird im Antwortbereich angezeigt. Der Antworttext ist leer, und der Statuscode ist 204.
Testen mit anderen Tools
Es gibt viele andere Tools, die zum Testen von Web-APIs verwendet werden können, z. B.:
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.
DTO wird in diesem Lernprogramm verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Eigenschaften ausblenden, die Kunden nicht sehen 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 Eines DTO-Modells in einer Models/TodoItemsDTO.cs-Datei :
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
Siehe Lernprogramm: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Siehe Video: Anfängerserie zu: Web-APIs.
Enterprise Web App-Muster
Anleitungen zum Erstellen einer zuverlässigen, sicheren, leistungsfähigen, testbaren und skalierbaren ASP.NET Core-App finden Sie unter Enterprise Web App-Muster. Eine vollständige Beispielweb-App zur Produktionsqualität, die die Muster implementiert, ist verfügbar.
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
- Föderationsgateway
Wichtig
Duende Software erfordert möglicherweise, dass Sie eine Lizenzgebühr für die Produktionsnutzung von Duende Identity Server bezahlen. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core in .NET 5 zu .NET 6.
Weitere Informationen finden Sie in der Duende Server-Dokumentation (Duende Identity Software-Website).
Veröffentlichen in Azure
Informationen zum Bereitstellen in Azure finden Sie in der Schnellstartanleitung: Bereitstellen einer ASP.NET Web-App.
Zusätzliche Ressourcen
Beispielcode für dieses Lernprogramm anzeigen oder herunterladen. Hier erfahren Sie, wie Sie herunterladen.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core
- Verwenden der generierten OpenAPI-Dokumente
- ASP.NET Core Web API-Dokumentation mit Swagger / OpenAPI
- Razor Seiten mit Entity Framework Core in ASP.NET Core - Lernprogramm 1 von 8
- Routing zu Controller-Aktionen in ASP.NET Core
- Rückgabetypen für Controlleraktionen in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps für 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 weiterer Ansatz zum Erstellen von APIs in ASP.NET Core besteht darin, minimale APIs zu erstellen. Hilfe bei der Auswahl zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Ein Lernprogramm zum Erstellen einer minimalen API finden Sie im Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
Programmierschnittstelle (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 | Aufgabenpunkt |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenpunkt | Aufgabenpunkt |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenpunkt | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit ASP.NET - und Webentwicklungsworkload .
Erstellen eines Webprojekts
- Wählen Sie im Menü "Datei" die Option "Neues Projekt"> aus.
- Geben Sie die Web-API in das Suchfeld ein.
- Wählen Sie die Vorlage ASP.NET Core Web API aus , und wählen Sie "Weiter" aus.
- Benennen Sie im Dialogfeld "Neues Projekt konfigurieren" das Projekt "TodoApi ", und wählen Sie "Weiter" aus.
- Im Dialogfeld "Zusätzliche Informationen ":
- Vergewissern Sie sich, dass das Framework.NET 8.0 (Langfristiger Support) ist.
- Vergewissern Sie sich, dass das Kontrollkästchen für die Verwendung von Controllern (deaktivieren, um minimale APIs zu verwenden) aktiviert ist.
- Bestätigen Sie, dass das Kontrollkästchen für die OpenAPI-Unterstützung aktiviert ist.
- Wählen Sie "Erstellen" aus.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Wählen Sie im Menü "Extras " die Option "NuGet-Paket-Manager > Verwalten von NuGet-Paketen für Lösung" aus.
- Wählen Sie die Registerkarte " Durchsuchen" aus .
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
dann aus. - Aktivieren Sie das Kontrollkästchen "Projekt " im rechten Bereich, und wählen Sie dann "Installieren" aus.
Hinweis
Anleitungen zum Hinzufügen von Paketen zu .NET-Apps finden Sie in den Artikeln unter "Installieren und Verwalten von Paketen" im Workflow "Paketverbrauch" (NuGet-Dokumentation). Bestätigen Sie die richtigen Paketversionen bei NuGet.org.
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-SSL-Zertifikat vertrauen.
Das folgende Dialogfeld wird angezeigt:
Wählen Sie "Ja " aus, wenn Sie dem Entwicklungszertifikat vertrauen möchten.
Informationen zum Vertrauen in den Firefox-Browser finden Sie unter Firefox SEC_ERROR_INADEQUATE_KEY_USAGE-Zertifikatfehler.
Visual Studio startet den Standardbrowser und navigiert zu https://localhost:<port>/swagger/index.html
, wobei <port>
eine zufällig bei der Projekterstellung festgelegte Portnummer ist.
Die Swagger-Seite /swagger/index.html
wird angezeigt. Wählen Sie GET>Try it out>Execute aus. Die Seite zeigt Folgendes an:
- Der Befehl "Curl ", um die WeatherForecast-API zu testen.
- 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 Seite "Swagger" nicht angezeigt wird, lesen Sie dieses GitHub-Problem.
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 in den 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 Reihe von Klassen, die die von der App verwalteten Daten darstellen. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Wählen Sie "Neuen Ordner>" aus. Geben Sie dem Ordner den Namen
Models
. - Klicken Sie mit der rechten Maustaste auf den
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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-Funktionalität 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
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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 im Container der Dependency Injection (DI) 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 DI-Container 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.
Wählen Sie API Controller mit Aktionen, mithilfe von Entity Framework, und wählen Sie dann "Hinzufügen" aus.
Im Dialogfenster "API-Controller mit Aktionen hinzufügen, unter Verwendung des Entitätsframeworks" :
- Wählen Sie TodoItem (TodoApi.Models) in der Model-Klasse aus.
- Wählen Sie TodoContext (TodoApi.Models) in der Data-Kontextklasse aus.
- Wählen Sie "Hinzufügen" aus.
Wenn der Gerüstvorgang fehlschlägt, wählen Sie "Hinzufügen" aus, um das Gerüst ein zweites Mal zu versuchen.
Der generierte Code:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen zu bestimmten Verhaltensweisen, die das Attribut ermöglicht, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet DI, um den Datenbankkontext (
TodoContext
) in den Controller zu injizieren. Der Datenbankkontext wird in den einzelnen CRUD-Methoden des Controllers 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 das [action]
Token nicht in der Routenvorlage enthalten ist, 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
, um den nameof-Operator zu verwenden.
[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 erfolgreicher Ausführung einen HTTP 201-Statuscode 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. Die
Location
Kopfzeile gibt den URI des neu erstellten to-do Elements an. Weitere Informationen finden Sie unter 10.2.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 " Ausprobieren" aus.
Aktualisieren Sie im Eingabefenster "Anfragekörper" den JSON-Code. Beispiel:
{ "name": "walk dog", "isComplete": true }
Wählen Sie "Ausführen" aus.
Testen des Adressheader-URIs
Im vorherigen Post zeigt die Swagger-Benutzeroberfläche den Location-Header unter Antwortheader an. Beispiel: location: https://localhost:7260/api/TodoItems/1
. Der Standort-Header zeigt den URI für die erstellte Ressource an.
Um den Standort-Header zu testen:
Wählen Sie im Swagger-Browserfenster GET /api/TodoItems/{id} und dann " Ausprobieren" aus.
Geben Sie
1
in dasid
Eingabefeld ein, und wählen Sie dann Ausführen 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 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. Für dieses Beispiel ist der Controllerklassenname TodoItemsController, sodass der Controllername "TodoItems" lautet. ASP.NET Core Routing ist nicht groß-/kleinschreibungssensitiv.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 Methode in ihrem Parameter "{id}"
der Wert von id
aus der URL 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 GetTodoItems
- und GetTodoItem
-Methoden ist vom ActionResult<T>-Typ. ASP.NET Core serialisiert das Objekt automatisch in JSON und schreibt den JSON-Code in den Textkörper der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine unbehandelten Ausnahmen. 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 den Fehlercode 404 zurückNotFound .
- 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 lautet 204 (Kein Inhalt). 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.
Die 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 Endpoints Explorer- und HTTP-Dateien
- http-repl
-
curl. Swagger verwendet
curl
und zeigt die gesendetencurl
-Befehle an. - Geiger
Weitere Informationen finden Sie unter
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.
DTO wird in diesem Lernprogramm verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Eigenschaften ausblenden, die Kunden nicht sehen 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
Siehe Lernprogramm: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Siehe Video: Anfängerserie zu: Web-APIs.
Enterprise Web App-Muster
Anleitungen zum Erstellen einer zuverlässigen, sicheren, leistungsfähigen, testbaren und skalierbaren ASP.NET Core-App finden Sie unter Enterprise Web App-Muster. Eine vollständige Beispielweb-App zur Produktionsqualität, die die Muster implementiert, ist verfügbar.
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
- Föderationsgateway
Wichtig
Duende Software erfordert möglicherweise, dass Sie eine Lizenzgebühr für die Produktionsnutzung von Duende Identity Server bezahlen. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core in .NET 5 zu .NET 6.
Weitere Informationen finden Sie in der Duende Server-Dokumentation (Duende Identity Software-Website).
Veröffentlichen in Azure
Informationen zum Bereitstellen in Azure finden Sie in der Schnellstartanleitung: Bereitstellen einer ASP.NET Web-App.
Zusätzliche Ressourcen
Beispielcode für dieses Lernprogramm anzeigen oder herunterladen. Hier erfahren Sie, wie Sie herunterladen.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core
- ASP.NET Core Web API-Dokumentation mit Swagger / OpenAPI
- Razor Seiten mit Entity Framework Core in ASP.NET Core - Lernprogramm 1 von 8
- Routing zu Controller-Aktionen in ASP.NET Core
- Rückgabetypen für Controlleraktionen in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps für 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 weiterer Ansatz zum Erstellen von APIs in ASP.NET Core besteht darin, minimale APIs zu erstellen. Hilfe bei der Auswahl zwischen minimalen APIs und controllerbasierten APIs finden Sie in der Übersicht über APIs. Ein Lernprogramm zum Erstellen einer minimalen API finden Sie im Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core.
Übersicht
In diesem Tutorial wird die folgende API erstellt:
Programmierschnittstelle (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 | Aufgabenpunkt |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenpunkt | Aufgabenpunkt |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenpunkt | Keine |
DELETE /api/todoitems/{id} |
Löschen eines Elements | Keine | Keine |
Das folgende Diagramm zeigt den Entwurf der App.
Voraussetzungen
Visual Studio 2022 mit ASP.NET - und Webentwicklungsworkload .
Erstellen eines Webprojekts
- Wählen Sie im Menü "Datei" die Option "Neues Projekt"> aus.
- Geben Sie die Web-API in das Suchfeld ein.
- Wählen Sie die Vorlage ASP.NET Core Web API aus , und wählen Sie "Weiter" aus.
- Benennen Sie im Dialogfeld "Neues Projekt konfigurieren" das Projekt "TodoApi ", und wählen Sie "Weiter" aus.
- Im Dialogfeld "Zusätzliche Informationen ":
- Vergewissern Sie sich, dass das Framework.NET 8.0 (Langfristiger Support) ist.
- Vergewissern Sie sich, dass das Kontrollkästchen für die Verwendung von Controllern (deaktivieren, um minimale APIs zu verwenden) aktiviert ist.
- Bestätigen Sie, dass das Kontrollkästchen für die OpenAPI-Unterstützung aktiviert ist.
- Wählen Sie "Erstellen" aus.
Hinzufügen eines NuGet-Pakets
Ein NuGet-Paket muss hinzugefügt werden, um die in diesem Tutorial verwendete Datenbank zu unterstützen.
- Wählen Sie im Menü "Extras " die Option "NuGet-Paket-Manager > Verwalten von NuGet-Paketen für Lösung" aus.
- Wählen Sie die Registerkarte " Durchsuchen" aus .
- Geben Sie Microsoft.EntityFrameworkCore.InMemory in das Suchfeld ein, und wählen Sie
Microsoft.EntityFrameworkCore.InMemory
dann aus. - Aktivieren Sie das Kontrollkästchen "Projekt " im rechten Bereich, und wählen Sie dann "Installieren" aus.
Hinweis
Anleitungen zum Hinzufügen von Paketen zu .NET-Apps finden Sie in den Artikeln unter "Installieren und Verwalten von Paketen" im Workflow "Paketverbrauch" (NuGet-Dokumentation). Bestätigen Sie die richtigen Paketversionen bei NuGet.org.
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-SSL-Zertifikat vertrauen.
Das folgende Dialogfeld wird angezeigt:
Wählen Sie "Ja " aus, wenn Sie dem Entwicklungszertifikat vertrauen möchten.
Informationen zum Vertrauen in den Firefox-Browser finden Sie unter Firefox SEC_ERROR_INADEQUATE_KEY_USAGE-Zertifikatfehler.
Visual Studio startet den Standardbrowser und navigiert zu https://localhost:<port>/swagger/index.html
, wobei <port>
eine zufällig bei der Projekterstellung festgelegte Portnummer ist.
Die Swagger-Seite /swagger/index.html
wird angezeigt. Wählen Sie GET>Try it out>Execute aus. Die Seite zeigt Folgendes an:
- Der Befehl "Curl ", um die WeatherForecast-API zu testen.
- 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 Seite "Swagger" nicht angezeigt wird, lesen Sie dieses GitHub-Problem.
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 in den 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 Reihe von Klassen, die die von der App verwalteten Daten darstellen. Das Modell für diese App ist die Klasse TodoItem
.
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt. Wählen Sie "Neuen Ordner>" aus. Geben Sie dem Ordner den Namen
Models
. - Klicken Sie mit der rechten Maustaste auf den
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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-Funktionalität 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
Models
Ordner, und wählen Sie "Klasse> aus. Benennen 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 im Container der Dependency Injection (DI) 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 DI-Container 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.
Wählen Sie API Controller mit Aktionen, mithilfe von Entity Framework, und wählen Sie dann "Hinzufügen" aus.
Im Dialogfenster "API-Controller mit Aktionen hinzufügen, unter Verwendung des Entitätsframeworks" :
- Wählen Sie TodoItem (TodoApi.Models) in der Model-Klasse aus.
- Wählen Sie TodoContext (TodoApi.Models) in der Data-Kontextklasse aus.
- Wählen Sie "Hinzufügen" aus.
Wenn der Gerüstvorgang fehlschlägt, wählen Sie "Hinzufügen" aus, um das Gerüst ein zweites Mal zu versuchen.
Der generierte Code:
- Markiert die Klasse mit dem
[ApiController]
-Attribut. Dieses Attribut gibt an, dass der Controller auf Web-API-Anforderungen reagiert. Informationen zu bestimmten Verhaltensweisen, die das Attribut ermöglicht, finden Sie unter Erstellen von Web-APIs mit ASP.NET Core. - Verwendet DI, um den Datenbankkontext (
TodoContext
) in den Controller zu injizieren. Der Datenbankkontext wird in den einzelnen CRUD-Methoden des Controllers 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 das [action]
Token nicht in der Routenvorlage enthalten ist, 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
, um den nameof-Operator zu verwenden.
[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 erfolgreicher Ausführung einen HTTP 201-Statuscode 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. Die
Location
Kopfzeile gibt den URI des neu erstellten to-do Elements an. Weitere Informationen finden Sie unter 10.2.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 " Ausprobieren" aus.
Aktualisieren Sie im Eingabefenster "Anfragekörper" den JSON-Code. Beispiel:
{ "name": "walk dog", "isComplete": true }
Wählen Sie "Ausführen" aus.
Testen des Adressheader-URIs
Im vorherigen Post zeigt die Swagger-Benutzeroberfläche den Location-Header unter Antwortheader an. Beispiel: location: https://localhost:7260/api/TodoItems/1
. Der Standort-Header zeigt den URI für die erstellte Ressource an.
Um den Standort-Header zu testen:
Wählen Sie im Swagger-Browserfenster GET /api/TodoItems/{id} und dann " Ausprobieren" aus.
Geben Sie
1
in dasid
Eingabefeld ein, und wählen Sie dann Ausführen 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 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. Für dieses Beispiel ist der Controllerklassenname TodoItemsController, sodass der Controllername "TodoItems" lautet. ASP.NET Core Routing ist nicht groß-/kleinschreibungssensitiv.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 Methode in ihrem Parameter "{id}"
der Wert von id
aus der URL 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 GetTodoItems
- und GetTodoItem
-Methoden ist vom ActionResult<T>-Typ. ASP.NET Core serialisiert das Objekt automatisch in JSON und schreibt den JSON-Code in den Textkörper der Antwortnachricht. Der Antwortcode für diesen Rückgabetyp ist 200 OK, vorausgesetzt, es gibt keine unbehandelten Ausnahmen. 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 den Fehlercode 404 zurückNotFound .
- 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 lautet 204 (Kein Inhalt). 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.
Die 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 Endpoints Explorer- und HTTP-Dateien
- http-repl
-
curl. Swagger verwendet
curl
und zeigt die gesendetencurl
-Befehle an. - Geiger
Weitere Informationen finden Sie unter
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.
DTO wird in diesem Lernprogramm verwendet.
Ein DTO kann für Folgendes verwendet werden:
- Vermeiden Sie Overposting.
- Eigenschaften ausblenden, die Kunden nicht sehen 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
Siehe Lernprogramm: Aufrufen einer ASP.NET Core-Web-API mit JavaScript.
Videoreihe zur Web-API
Siehe Video: Anfängerserie zu: Web-APIs.
Enterprise Web App-Muster
Anleitungen zum Erstellen einer zuverlässigen, sicheren, leistungsfähigen, testbaren und skalierbaren ASP.NET Core-App finden Sie unter Enterprise Web App-Muster. Eine vollständige Beispielweb-App zur Produktionsqualität, die die Muster implementiert, ist verfügbar.
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
- Föderationsgateway
Wichtig
Duende Software erfordert möglicherweise, dass Sie eine Lizenzgebühr für die Produktionsnutzung von Duende Identity Server bezahlen. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core in .NET 5 zu .NET 6.
Weitere Informationen finden Sie in der Duende Server-Dokumentation (Duende Identity Software-Website).
Veröffentlichen in Azure
Informationen zum Bereitstellen in Azure finden Sie in der Schnellstartanleitung: Bereitstellen einer ASP.NET Web-App.
Zusätzliche Ressourcen
Beispielcode für dieses Lernprogramm anzeigen oder herunterladen. Hier erfahren Sie, wie Sie herunterladen.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Erstellen von Web-APIs mit ASP.NET Core
- Lernprogramm: Erstellen einer minimalen API mit ASP.NET Core
- ASP.NET Core Web API-Dokumentation mit Swagger / OpenAPI
- Razor Seiten mit Entity Framework Core in ASP.NET Core - Lernprogramm 1 von 8
- Routing zu Controller-Aktionen in ASP.NET Core
- Rückgabetypen für Controlleraktionen in ASP.NET Core-Web-API
- Bereitstellen von ASP.NET Core-Apps für Azure App Service
- Hosten und Bereitstellen von ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core