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.
Note
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Warning
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.
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 Entscheidung 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.
Overview
In diesem Tutorial wird die folgende API erstellt:
| API | Description | Anfragekörper | Antworttext |
|---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | None | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | None | Aufgabenelement |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenelement | Aufgabenelement |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenelement | None |
DELETE /api/todoitems/{id} |
Löschen eines Elements | None | None |
Das folgende Diagramm zeigt den Entwurf der App.
Prerequisites
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.InMemoryaus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Note
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). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
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-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 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. Da auf https://localhost:<port> kein Endpunkt vorhanden ist, 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
ModelsOrdner, 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
ModelsOrdner, 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 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 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ückgabe-Anweisung in der PostTodoItem zu verwendenden Nameofoperator :
[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 201ist die Standardantwort für eineHTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Die
LocationKopfzeile 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.
PostTodoItem testen
Wählen Sie Ansicht>Weitere Fenster>Endpunkt-Explorer aus.
Klicken Sie mit der rechten Maustaste auf den POST-Endpunkt, und wählen Sie Anforderung generieren aus.
Im Projektordner mit dem Namen
TodoApi.httpwird 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//TodoItemKommentar 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 Anforderung senden aus. Er befindet sich oberhalb der
POST-Anforderungszeile.
Die POST-Anforderung wird an die App gesendet, und die Antwort wird im Bereich Antwort angezeigt.
Testen des Adressheader-URIs
Testen Sie die App, indem Sie die GET-Endpunkte in einem Browser aufrufen oder indem Sie den Endpunkte-Explorer verwenden. Die folgenden Schritte gelten für Endpunkt-Explorer.
Klicken Sie im Endpunkte-Explorer mit der rechten Maustaste auf den ersten GET-Endpunkt, und wählen Sie Anforderung generieren aus.
Der folgende Inhalt wird der datei
TodoApi.httphinzugefügt:GET {{TodoApi_HostAddress}}/api/todoitems ###Wählen Sie den Link Anforderung senden aus. Er befindet sich oberhalb der neuen
GET-Anforderungszeile.Die GET-Anforderung wird an die App gesendet, und die Antwort wird im Bereich Antwort angezeigt.
Der Antwortkörper ähnelt dem folgenden JSON.
[ { "id": 1, "name": "walk dog", "isComplete": true } ]Klicken Sie im Endpunkte-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.httphinzugefü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 Bereich Antwort 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/todoitemsGET /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, werden POST-Daten an die App zurückgegeben.
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 : ControllerBaseErsetzen 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 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 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 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 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 einen 404 StatusNotFound-Fehlercode zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
itemlö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 Endpunkte-Explorer mit der rechten Maustaste auf den PUT-Endpunkt, und wählen Sie Anforderung generieren aus.
Der folgende Inhalt wird der datei
TodoApi.httphinzugefügt:PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}} Content-Type: application/json { //TodoItem } ###Ersetzen Sie in der PUT-Anforderungszeile
{{id}}durch1.Ersetzen Sie den Platzhalter
//TodoItemdurch 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 Bereich Antwort 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 Endpunkte-Explorer mit der rechten Maustaste auf den DELETE-Endpunkt, und wählen Sie Anforderung generieren aus.
Eine DELETE-Anforderung wird zu
TodoApi.httphinzugefü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 Bereich Antwort 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.:
Verhindern von Überbuchungen
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:
- Verhindern von Überbuchungen.
- 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
Important
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.
Weitere 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 Controlleraktionen 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 Entscheidung 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.
Overview
In diesem Tutorial wird die folgende API erstellt:
| API | Description | Anfragekörper | Antworttext |
|---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | None | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | None | Aufgabenelement |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenelement | Aufgabenelement |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenelement | None |
DELETE /api/todoitems/{id} |
Löschen eines Elements | None | None |
Das folgende Diagramm zeigt den Entwurf der App.
Prerequisites
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.InMemoryaus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Note
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). Ü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 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
ModelsOrdner, 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
ModelsOrdner, 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 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 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ückgabe-Anweisung in der PostTodoItem zu verwendenden Nameofoperator :
[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 201ist die Standardantwort für eineHTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Die
LocationKopfzeile 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.
PostTodoItem testen
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 " Textkörper anfordern " den JSON-Code. Beispiel:
{ "name": "walk dog", "isComplete": true }Wählen Sie "Ausführen" aus.
Testen des Adressheader-URIs
In der vorherigen POST zeigt die Swagger-Benutzeroberfläche den Positionsheader 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
1dasidEingabefeld ein, und wählen Sie dann "Ausführen" aus.
Überblick über die GET-Methoden
Zwei GET-Endpunkte werden implementiert:
GET /api/todoitemsGET /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, werden POST-Daten an die App zurückgegeben.
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 : ControllerBaseErsetzen 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 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 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 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 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 einen 404 StatusNotFound-Fehlercode zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
itemlö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
curlund zeigt die gesendetencurl-Befehle an. - Fiddler
Weitere Informationen finden Sie unter
Verhindern von Überbuchungen
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:
- Verhindern von Überbuchungen.
- 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
Important
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.
Weitere 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 Controlleraktionen 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 Entscheidung 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.
Overview
In diesem Tutorial wird die folgende API erstellt:
| API | Description | Anfragekörper | Antworttext |
|---|---|---|---|
GET /api/todoitems |
Alle To-do-Elemente abrufen | None | Array von To-do-Elementen |
GET /api/todoitems/{id} |
Ein Element nach ID abrufen | None | Aufgabenelement |
POST /api/todoitems |
Neues Element hinzufügen | Aufgabenelement | Aufgabenelement |
PUT /api/todoitems/{id} |
Vorhandenes Element aktualisieren | Aufgabenelement | None |
DELETE /api/todoitems/{id} |
Löschen eines Elements | None | None |
Das folgende Diagramm zeigt den Entwurf der App.
Prerequisites
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.InMemoryaus. - Aktivieren Sie das Kontrollkästchen Projekt im rechten Bereich, und klicken Sie dann auf Installieren.
Note
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). Ü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 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
ModelsOrdner, 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
ModelsOrdner, 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 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 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ückgabe-Anweisung in der PostTodoItem zu verwendenden Nameofoperator :
[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 201ist die Standardantwort für eineHTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. - Fügt der Antwort einen Location-Header hinzu. Die
LocationKopfzeile 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.
PostTodoItem testen
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 " Textkörper anfordern " den JSON-Code. Beispiel:
{ "name": "walk dog", "isComplete": true }Wählen Sie "Ausführen" aus.
Testen des Adressheader-URIs
In der vorherigen POST zeigt die Swagger-Benutzeroberfläche den Positionsheader 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
1dasidEingabefeld ein, und wählen Sie dann "Ausführen" aus.
Überblick über die GET-Methoden
Zwei GET-Endpunkte werden implementiert:
GET /api/todoitemsGET /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, werden POST-Daten an die App zurückgegeben.
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 : ControllerBaseErsetzen 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 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 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 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 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 einen 404 StatusNotFound-Fehlercode zurück.
- Andernfalls gibt die Methode 200 mit einem JSON-Antworttext zurück. Die Rückgabe von
itemlö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
curlund zeigt die gesendetencurl-Befehle an. - Fiddler
Weitere Informationen finden Sie unter
Verhindern von Überbuchungen
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:
- Verhindern von Überbuchungen.
- 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
Important
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.
Weitere 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 Controlleraktionen 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