Share via


Erstellen einer Web-API mit ASP.NET Core und MongoDB

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Von Pratik Khandelwal und Scott Addie

Dieses Tutorial erstellt eine Web-API, die CRUD-Vorgänge (Create, Read, Update, Delete) für eine MongoDB-NoSQL-Datenbank durchführt.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Konfigurieren von MongoDB
  • Erstellen einer MongoDB-Datenbank
  • Definieren einer MongoDB-Sammlung und eines Schemas
  • Ausführen von MongoDB-CRUD-Vorgänge über eine Web-API
  • Anpassen der JSON-Serialisierung

Voraussetzungen

Konfigurieren von MongoDB

Aktivieren Sie den Zugriff von MongoDB und MongoDB Shell von überall auf dem Entwicklungscomputer (Windows/Linux/macOS):

  1. MongoDB Shell herunterladen und installieren:

    • macOS/Linux: Wählen Sie ein Verzeichnis aus, in das die MongoDB-Shell extrahiert werden soll. Fügen Sie der PATH-Umgebungsvariablen den resultierenden Pfad für mongosh hinzu.
    • Windows: MongoDB Shell (mongosh.exe) wird unter C:\Users<user>\AppData\Local\Programs\mongosh installiert. Fügen Sie der PATH-Umgebungsvariablen den resultierenden Pfad für mongosh.exe hinzu.
  2. MongoDB herunterladen und installieren:

    • macOS/Linux: Überprüfen Sie das Verzeichnis, unter dem MongoDB installiert wurde, in der Regel in /usr/local/mongodb. Fügen Sie der PATH-Umgebungsvariablen den resultierenden Pfad für mongodb hinzu.
    • Windows: MongoDB wird standardmäßig unter C:\Programme\MongoDB installiert. Fügen Sie der Umgebungsvariablen PATH den Pfad C:\Programme\MongoDB\Server\<version_number>\bin hinzu.
  3. Wählen Sie ein Datenspeicherverzeichnis aus: Wählen Sie ein Verzeichnis auf Ihrem Entwicklungscomputer zum Speichern von Daten aus. Erstellen Sie das Verzeichnis, falls es nicht vorhanden ist. Die MongoDB Shell erstellt keine neuen Verzeichnisse:

    • macOS/Linux: Zum Beispiel /usr/local/var/mongodb.
    • Windows: Zum Beispiel C:\\BooksData.
  4. Verwenden Sie in der Befehlsshell des Betriebssystems (nicht in der MongoDB-Shell) den folgenden Befehl, um eine Verbindung mit MongoDB am Standardport 27017 herzustellen. Ersetzen Sie <data_directory_path> durch das im vorherigen Schritt ausgewählte Verzeichnis.

    mongod --dbpath <data_directory_path>
    

Verwenden Sie die zuvor installierte MongoDB-Shell in den folgenden Schritten, um eine Datenbank zu erstellen, Sammlungen durchzuführen und Dokumente zu speichern. Weitere Informationen zu MongoDB-Shell-Befehlen finden Sie unter mongosh.

  1. Öffnen Sie eine Instanz der MongoDB-Befehlsshell, indem Sie mongosh.exe starten.

  2. Stellen Sie in der Befehlsshell eine Verbindung mit der Standardtestdatenbank her, indem Sie den folgenden Befehl ausführen:

    mongosh
    
  3. Führen Sie den folgenden Befehl in der Befehlsshell aus:

    use BookStore
    

    Wenn nicht bereits vorhanden, wird eine Datenbank namens BookStore erstellt. Wenn die Datenbank vorhanden ist, wird die Verbindung für Transaktionen geöffnet.

  4. Erstellen Sie eine Books-Sammlung mithilfe des folgenden Befehls:

    db.createCollection('Books')
    

    Das folgende Ergebnis wird angezeigt:

    { "ok" : 1 }
    
  5. Definieren Sie ein Schema für die Books-Sammlung. und fügen zwei Dokumente mithilfe des folgenden Befehls ein:

    db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("61a6058e6c43f32854e51f51"),
            ObjectId("61a6058e6c43f32854e51f52")
         ]
     }
    

    Hinweis

    Die im vorherigen Ergebnis angezeigten ObjectIds stimmen nicht mit denen überein, die in der Befehlsshell angezeigt werden.

  6. Zeigen Sie die Dokumente in der Datenbank mithilfe des folgenden Befehls an:

    db.Books.find().pretty()
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
         "_id" : ObjectId("61a6058e6c43f32854e51f51"),
         "Name" : "Design Patterns",
         "Price" : 54.93,
         "Category" : "Computers",
         "Author" : "Ralph Johnson"
     }
     {
         "_id" : ObjectId("61a6058e6c43f32854e51f52"),
         "Name" : "Clean Code",
         "Price" : 43.15,
         "Category" : "Computers",
         "Author" : "Robert C. Martin"
     }
    

    Das Schema fügt eine automatisch generierte _id Eigenschaft vom Typ ObjectId für jedes Dokument hinzu.

Erstellen eines ASP.NET Core-Web-API-Projektes

  1. Wechseln Sie zu Datei>Neu>Projekt.

  2. Wählen Sie den Projekttyp ASP.NET Core-Web-API aus, und klicken Sie auf Weiter.

  3. Geben Sie dem Projekt den Namen BookStoreApi, und klicken Sie auf Weiter.

  4. Wählen Sie das Framework .NET 8.0 (langfristiger Support) und dann Erstellen aus.

  5. Navigieren Sie im Fenster Paket-Manager-Konsole zum Stammverzeichnis des Projekts. Führen Sie den folgenden Befehl aus, um den .NET-Treiber für MongoDB zu installieren:

    Install-Package MongoDB.Driver
    

Hinzufügen eines Entitätsmodells

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Modelle hinzu.

  2. Fügen Sie eine Book-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BookStoreApi.Models;
    
    public class Book
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string? Id { get; set; }
    
        [BsonElement("Name")]
        public string BookName { get; set; } = null!;
    
        public decimal Price { get; set; }
    
        public string Category { get; set; } = null!;
    
        public string Author { get; set; } = null!;
    }
    

    In der obigen Klasse gilt für die Id-Eigenschaft Folgendes:

    • Sie ist erforderlich, um der MongoDB-Sammlung das CLR-Objekt (Common Language Runtime) zuzuordnen.
    • Sie wird mit [BsonId] kommentiert, um diese Eigenschaft als Primärschlüssel des Dokuments festzulegen.
    • Sie wird mit [BsonRepresentation(BsonType.ObjectId)] kommentiert, um die Übergabe des Parameters als Typ string anstelle einer ObjectId-Struktur zu ermöglichen. Mongo behandelt die Konvertierung von string zu ObjectId.

    Die Eigenschaft BookName ist mit dem Attribut [BsonElement] versehen. Der Wert Name des Attributs stellt den Eigenschaftsnamen in der MongoDB-Sammlung dar.

Hinzufügen eines Konfigurationsmodells

  1. Fügen Sie appsettings.json die folgenden Konfigurationswerte für die Datenbank hinzu:

    {
        "BookStoreDatabase": {
            "ConnectionString": "mongodb://localhost:27017",
            "DatabaseName": "BookStore",
            "BooksCollectionName": "Books"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning"
            }
        },
        "AllowedHosts": "*"
    }
    
  2. Fügen Sie eine BookStoreDatabaseSettings-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    namespace BookStoreApi.Models;
    
    public class BookStoreDatabaseSettings
    {
        public string ConnectionString { get; set; } = null!;
    
        public string DatabaseName { get; set; } = null!;
    
        public string BooksCollectionName { get; set; } = null!;
    }
    

    Mit der vorhergehenden Klasse BookStoreDatabaseSettings werden die Eigenschaftswerte BookStoreDatabase der Datei appsettings.json gespeichert. Die Namen der JSON- und der C#-Eigenschaften sind identisch, um den Zuordnungsprozess zu erleichtern.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    

    Im obigen Code wird die Konfigurationsinstanz, an die der Abschnitt BookStoreDatabase der Datei appsettings.json gebunden ist, beim DI-Container (Dependency Injection) registriert. Beispielsweise wird die Eigenschaft ConnectionString des BookStoreDatabaseSettings-Objekts mit der Eigenschaft BookStoreDatabase:ConnectionString in appsettings.json aufgefüllt.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BookStoreDatabaseSettings aufzulösen:

    using BookStoreApi.Models;
    

Hinzufügen eines CRUD-Vorgangsdiensts

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Dienste hinzu.

  2. Fügen Sie eine BooksService-Klasse zum Verzeichnis Dienste mit dem folgenden Code hinzu:

    using BookStoreApi.Models;
    using Microsoft.Extensions.Options;
    using MongoDB.Driver;
    
    namespace BookStoreApi.Services;
    
    public class BooksService
    {
        private readonly IMongoCollection<Book> _booksCollection;
    
        public BooksService(
            IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
        {
            var mongoClient = new MongoClient(
                bookStoreDatabaseSettings.Value.ConnectionString);
    
            var mongoDatabase = mongoClient.GetDatabase(
                bookStoreDatabaseSettings.Value.DatabaseName);
    
            _booksCollection = mongoDatabase.GetCollection<Book>(
                bookStoreDatabaseSettings.Value.BooksCollectionName);
        }
    
        public async Task<List<Book>> GetAsync() =>
            await _booksCollection.Find(_ => true).ToListAsync();
    
        public async Task<Book?> GetAsync(string id) =>
            await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
    
        public async Task CreateAsync(Book newBook) =>
            await _booksCollection.InsertOneAsync(newBook);
    
        public async Task UpdateAsync(string id, Book updatedBook) =>
            await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
    
        public async Task RemoveAsync(string id) =>
            await _booksCollection.DeleteOneAsync(x => x.Id == id);
    }
    

    Im vorhergehenden Code wird eine BookStoreDatabaseSettings-Instanz mittels Konstruktorinjektion über DI abgerufen. Damit kann auf die Konfigurationswerte von appsettings.json zugegriffen werden, die im Abschnitt Hinzufügen eines Konfigurationsmodells hinzugefügt wurden.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    

    Im vorhergehenden Code wird die Klasse BooksService bei DI registriert, um die Konstruktorinjektion in verarbeitenden Klassen zu unterstützen. Die Lebensdauer des Singletondiensts ist am besten geeignet, da BooksService direkt von MongoClient abhängig ist. Gemäß den offiziellen Mongo Client-Richtlinien zur Wiederverwendung (Mongo Client reuse guidelines) sollte MongoClient bei DI mit der Lebensdauer eines Singletondiensts registriert werden.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BooksService aufzulösen:

    using BookStoreApi.Services;
    

Die BooksService-Klasse verwendet die folgenden MongoDB.Driver-Member, um CRUD-Vorgänge für die Datenbank auszuführen:

  • MongoClient: Liest die Serverinstanz zum Ausführen von Datenbankvorgängen. Der Konstruktor dieser Klasse wird in der MongoDB-Verbindungszeichenfolge bereitgestellt:

    public BooksService(
        IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
    {
        var mongoClient = new MongoClient(
            bookStoreDatabaseSettings.Value.ConnectionString);
    
        var mongoDatabase = mongoClient.GetDatabase(
            bookStoreDatabaseSettings.Value.DatabaseName);
    
        _booksCollection = mongoDatabase.GetCollection<Book>(
            bookStoreDatabaseSettings.Value.BooksCollectionName);
    }
    
  • IMongoDatabase: Stellt die Mongo-Datenbank zum Ausführen von Vorgängen dar. In diesem Tutorial wird die generische Methode GetCollection<TDocument>(collection) für die Schnittstelle verwendet, um Zugriff auf Daten in einer bestimmten Sammlung zu erhalten. Führen Sie CRUD-Vorgänge für die Sammlung aus, nachdem diese Methode aufgerufen wurde. Rufen Sie in der GetCollection<TDocument>(collection)-Methode folgendes auf:

    • collection steht für den Sammlungsnamen.
    • TDocument steht für den in der Sammlung gespeicherten CLR-Objekttypen.

GetCollection<TDocument>(collection) gibt ein MongoCollection-Objekt zurück, das die Sammlung darstellt. In diesem Tutorial werden die folgenden Methoden für der Sammlung aufgerufen:

  • DeleteOneAsync: Löscht ein einzelnes Dokument, das den angegebenen Suchkriterien entspricht.
  • Find<TDocument>: Gibt alle Dokumente in der Sammlung zurück, die den angegebenen Suchkriterien entsprechen.
  • InsertOneAsync: Fügt das angegebene Objekt als neues Dokument in die Sammlung ein.
  • ReplaceOneAsync: Ersetzt das einzelne Dokument, das den angegebenen Suchkriterien entspricht, durch das angegebene Objekt.

Hinzufügen eines Controllers

Fügen Sie eine BooksController-Klasse zum Verzeichnis Controller mit dem folgenden Code hinzu:

using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;

namespace BookStoreApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
    private readonly BooksService _booksService;

    public BooksController(BooksService booksService) =>
        _booksService = booksService;

    [HttpGet]
    public async Task<List<Book>> Get() =>
        await _booksService.GetAsync();

    [HttpGet("{id:length(24)}")]
    public async Task<ActionResult<Book>> Get(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        return book;
    }

    [HttpPost]
    public async Task<IActionResult> Post(Book newBook)
    {
        await _booksService.CreateAsync(newBook);

        return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
    }

    [HttpPut("{id:length(24)}")]
    public async Task<IActionResult> Update(string id, Book updatedBook)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        updatedBook.Id = book.Id;

        await _booksService.UpdateAsync(id, updatedBook);

        return NoContent();
    }

    [HttpDelete("{id:length(24)}")]
    public async Task<IActionResult> Delete(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        await _booksService.RemoveAsync(id);

        return NoContent();
    }
}

Der oben aufgeführte Web-API-Controller:

  • Verwendet die BooksService-Klasse, um CRUD-Vorgänge auszuführen.
  • Enthält Aktionsmethoden zur Unterstützung von GET-, POST-, PUT- und DELETE HTTP-Anforderungen.
  • Ruft CreatedAtAction in der Aktionsmethode Create auf, um eine HTTP 201-Antwort zurückzugeben. Der Statuscode 201 ist die Standardantwort für eine HTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. CreatedAtAction fügt der Antwort außerdem einen Location-Header hinzu. Der Location-Header gibt den URI des neu erstellten Buchs an.

Testen der Web-API

  1. Erstellen Sie die App, und führen Sie sie aus.

  2. Navigieren Sie zu https://localhost:<port>/api/books, wobei <port> die automatisch zugewiesene Portnummer für die App ist, um die parameterlose Get-Aktionsmethode des Controllers zu testen, wählen Sie Testen sie>Ausführen aus. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    [
      {
        "id": "61a6058e6c43f32854e51f51",
        "bookName": "Design Patterns",
        "price": 54.93,
        "category": "Computers",
        "author": "Ralph Johnson"
      },
      {
        "id": "61a6058e6c43f32854e51f52",
        "bookName": "Clean Code",
        "price": 43.15,
        "category": "Computers",
        "author": "Robert C. Martin"
      }
    ]
    
  3. Wechseln Sie zu https://localhost:<port>/api/books/{id here}, um die überladene Aktionsmethode Get des Controllers zu testen. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    {
      "id": "61a6058e6c43f32854e51f52",
      "bookName": "Clean Code",
      "price": 43.15,
      "category": "Computers",
      "author": "Robert C. Martin"
    }
    

Konfigurieren von JSON-Serialisierungsoptionen

Es gibt zwei Details, die bei JSON-Antworten zu ändern sind, die im Abschnitt Testen der Web-API zurückgegeben werden:

  • Die Camel-Case-Standardschreibweise von Eigenschaftsnamen sollte so geändert werden, dass sie der Pascal-Schreibweise der Eigenschaften des CLR-Objekts entspricht.
  • Die Eigenschaft bookName sollte als Name zurückgegeben werden.

Um die zuvor genannten Anforderungen zu erfüllen, nehmen Sie die folgenden Änderungen vor:

  1. Verketten Sie in Program.cs den folgenden hervorgehobenen Code mit dem Aufruf der AddControllers-Methode:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    
    builder.Services.AddControllers()
        .AddJsonOptions(
            options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
    

    Durch die vorherige Änderung stimmen Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API mit ihren entsprechenden Eigenschaftsnamen im CLR-Objekttyp überein. Beispielsweise wird die Eigenschaft Author der Book-Klasse als Author und nicht als author serialisiert.

  2. Kommentieren Sie in Models/Book.cs die BookName-Eigenschaft mit dem [JsonPropertyName]-Attribut:

    [BsonElement("Name")]
    [JsonPropertyName("Name")]
    public string BookName { get; set; } = null!;
    

    Der Wert Name des [JsonPropertyName]-Attributs stellt den Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API dar.

  3. Fügen Sie den folgenden Code am Anfang von Models/Book.cs hinzu, um den Verweis auf das [JsonProperty]-Attribut aufzulösen:

    using System.Text.Json.Serialization;
    
  4. Wiederholen Sie die im Abschnitt Testen der Web-API definierten Schritte. Beachten Sie den Unterschied bei den JSON-Eigenschaftsnamen.

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:

Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Wichtig

Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.

Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).

Zusätzliche Ressourcen

Dieses Tutorial erstellt eine Web-API, die CRUD-Vorgänge (Create, Read, Update, Delete) für eine MongoDB-NoSQL-Datenbank durchführt.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Konfigurieren von MongoDB
  • Erstellen einer MongoDB-Datenbank
  • Definieren einer MongoDB-Sammlung und eines Schemas
  • Ausführen von MongoDB-CRUD-Vorgänge über eine Web-API
  • Anpassen der JSON-Serialisierung

Voraussetzungen

Konfigurieren von MongoDB

Ermöglichen Sie den Zugriff auf MongoDB und die Mongo DB-Shell überall auf dem Entwicklungscomputer:

  1. Unter Windows wird MongoDB standardmäßig unter C:\Programme\MongoDB installiert. Fügen Sie der Umgebungsvariablen PATH den Pfad C:\Programme\MongoDB\Server\<version_number>\bin hinzu.

  2. Laden Sie die MongoDB-Shell herunter, und wählen Sie ein Verzeichnis aus, in das sie extrahiert werden soll. Fügen Sie der PATH-Umgebungsvariablen den resultierenden Pfad für mongosh.exe hinzu.

  3. Wählen Sie auf dem Entwicklungscomputer ein Verzeichnis zum Speichern der Daten aus. Zum Beispiel C:\BooksData auf Windows. Erstellen Sie das Verzeichnis, falls es nicht vorhanden ist. Die Mongo-Shell erstellt keine neuen Verzeichnisse.

  4. Verwenden Sie in der Befehlsshell des Betriebssystems (nicht in der MongoDB-Shell) den folgenden Befehl, um eine Verbindung mit MongoDB am Standardport 27017 herzustellen. Ersetzen Sie <data_directory_path> durch das im vorherigen Schritt ausgewählte Verzeichnis.

    mongod --dbpath <data_directory_path>
    

Verwenden Sie die zuvor installierte MongoDB-Shell in den folgenden Schritten, um eine Datenbank zu erstellen, Sammlungen durchzuführen und Dokumente zu speichern. Weitere Informationen zu MongoDB-Shell-Befehlen finden Sie unter mongosh.

  1. Öffnen Sie eine Instanz der MongoDB-Befehlsshell, indem Sie mongosh.exe starten.

  2. Stellen Sie in der Befehlsshell eine Verbindung mit der Standardtestdatenbank her, indem Sie den folgenden Befehl ausführen:

    mongosh
    
  3. Führen Sie den folgenden Befehl in der Befehlsshell aus:

    use BookStore
    

    Wenn nicht bereits vorhanden, wird eine Datenbank namens BookStore erstellt. Wenn die Datenbank vorhanden ist, wird die Verbindung für Transaktionen geöffnet.

  4. Erstellen Sie eine Books-Sammlung mithilfe des folgenden Befehls:

    db.createCollection('Books')
    

    Das folgende Ergebnis wird angezeigt:

    { "ok" : 1 }
    
  5. Definieren Sie ein Schema für die Books-Sammlung. und fügen zwei Dokumente mithilfe des folgenden Befehls ein:

    db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("61a6058e6c43f32854e51f51"),
            ObjectId("61a6058e6c43f32854e51f52")
         ]
     }
    

    Hinweis

    Die im vorherigen Ergebnis angezeigten ObjectIds stimmen nicht mit denen überein, die in der Befehlsshell angezeigt werden.

  6. Zeigen Sie die Dokumente in der Datenbank mithilfe des folgenden Befehls an:

    db.Books.find().pretty()
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
         "_id" : ObjectId("61a6058e6c43f32854e51f51"),
         "Name" : "Design Patterns",
         "Price" : 54.93,
         "Category" : "Computers",
         "Author" : "Ralph Johnson"
     }
     {
         "_id" : ObjectId("61a6058e6c43f32854e51f52"),
         "Name" : "Clean Code",
         "Price" : 43.15,
         "Category" : "Computers",
         "Author" : "Robert C. Martin"
     }
    

    Das Schema fügt eine automatisch generierte _id Eigenschaft vom Typ ObjectId für jedes Dokument hinzu.

Erstellen eines ASP.NET Core-Web-API-Projektes

  1. Wechseln Sie zu Datei>Neu>Projekt.

  2. Wählen Sie den Projekttyp ASP.NET Core-Web-API aus, und klicken Sie auf Weiter.

  3. Geben Sie dem Projekt den Namen BookStoreApi, und klicken Sie auf Weiter.

  4. Wählen Sie das Framework .NET 7.0 (Standard-Laufzeitunterstützung) und dann Erstellen aus.

  5. Wählen Sie im Menü Extras die Optionen NuGet-Paket-Manager>Paket-Manager-Konsole aus.

  6. Navigieren Sie im Fenster Paket-Manager-Konsole zum Stammverzeichnis des Projekts. Führen Sie den folgenden Befehl aus, um den .NET-Treiber für MongoDB zu installieren:

    Install-Package MongoDB.Driver
    

Hinzufügen eines Entitätsmodells

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Modelle hinzu.

  2. Fügen Sie eine Book-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BookStoreApi.Models;
    
    public class Book
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string? Id { get; set; }
    
        [BsonElement("Name")]
        public string BookName { get; set; } = null!;
    
        public decimal Price { get; set; }
    
        public string Category { get; set; } = null!;
    
        public string Author { get; set; } = null!;
    }
    

    In der obigen Klasse gilt für die Id-Eigenschaft Folgendes:

    • Sie ist erforderlich, um der MongoDB-Sammlung das CLR-Objekt (Common Language Runtime) zuzuordnen.
    • Sie wird mit [BsonId] kommentiert, um diese Eigenschaft als Primärschlüssel des Dokuments festzulegen.
    • Sie wird mit [BsonRepresentation(BsonType.ObjectId)] kommentiert, um die Übergabe des Parameters als Typ string anstelle einer ObjectId-Struktur zu ermöglichen. Mongo behandelt die Konvertierung von string zu ObjectId.

    Die Eigenschaft BookName ist mit dem Attribut [BsonElement] versehen. Der Wert Name des Attributs stellt den Eigenschaftsnamen in der MongoDB-Sammlung dar.

Hinzufügen eines Konfigurationsmodells

  1. Fügen Sie appsettings.json die folgenden Konfigurationswerte für die Datenbank hinzu:

    {
      "BookStoreDatabase": {
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookStore",
        "BooksCollectionName": "Books"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    
  2. Fügen Sie eine BookStoreDatabaseSettings-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    namespace BookStoreApi.Models;
    
    public class BookStoreDatabaseSettings
    {
        public string ConnectionString { get; set; } = null!;
    
        public string DatabaseName { get; set; } = null!;
    
        public string BooksCollectionName { get; set; } = null!;
    }
    

    Mit der vorhergehenden Klasse BookStoreDatabaseSettings werden die Eigenschaftswerte BookStoreDatabase der Datei appsettings.json gespeichert. Die Namen der JSON- und der C#-Eigenschaften sind identisch, um den Zuordnungsprozess zu erleichtern.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    

    Im obigen Code wird die Konfigurationsinstanz, an die der Abschnitt BookStoreDatabase der Datei appsettings.json gebunden ist, beim DI-Container (Dependency Injection) registriert. Beispielsweise wird die Eigenschaft ConnectionString des BookStoreDatabaseSettings-Objekts mit der Eigenschaft BookStoreDatabase:ConnectionString in appsettings.json aufgefüllt.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BookStoreDatabaseSettings aufzulösen:

    using BookStoreApi.Models;
    

Hinzufügen eines CRUD-Vorgangsdiensts

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Dienste hinzu.

  2. Fügen Sie eine BooksService-Klasse zum Verzeichnis Dienste mit dem folgenden Code hinzu:

    using BookStoreApi.Models;
    using Microsoft.Extensions.Options;
    using MongoDB.Driver;
    
    namespace BookStoreApi.Services;
    
    public class BooksService
    {
        private readonly IMongoCollection<Book> _booksCollection;
    
        public BooksService(
            IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
        {
            var mongoClient = new MongoClient(
                bookStoreDatabaseSettings.Value.ConnectionString);
    
            var mongoDatabase = mongoClient.GetDatabase(
                bookStoreDatabaseSettings.Value.DatabaseName);
    
            _booksCollection = mongoDatabase.GetCollection<Book>(
                bookStoreDatabaseSettings.Value.BooksCollectionName);
        }
    
        public async Task<List<Book>> GetAsync() =>
            await _booksCollection.Find(_ => true).ToListAsync();
    
        public async Task<Book?> GetAsync(string id) =>
            await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
    
        public async Task CreateAsync(Book newBook) =>
            await _booksCollection.InsertOneAsync(newBook);
    
        public async Task UpdateAsync(string id, Book updatedBook) =>
            await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
    
        public async Task RemoveAsync(string id) =>
            await _booksCollection.DeleteOneAsync(x => x.Id == id);
    }
    

    Im vorhergehenden Code wird eine BookStoreDatabaseSettings-Instanz mittels Konstruktorinjektion über DI abgerufen. Damit kann auf die Konfigurationswerte von appsettings.json zugegriffen werden, die im Abschnitt Hinzufügen eines Konfigurationsmodells hinzugefügt wurden.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    

    Im vorhergehenden Code wird die Klasse BooksService bei DI registriert, um die Konstruktorinjektion in verarbeitenden Klassen zu unterstützen. Die Lebensdauer des Singletondiensts ist am besten geeignet, da BooksService direkt von MongoClient abhängig ist. Gemäß den offiziellen Mongo Client-Richtlinien zur Wiederverwendung (Mongo Client reuse guidelines) sollte MongoClient bei DI mit der Lebensdauer eines Singletondiensts registriert werden.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BooksService aufzulösen:

    using BookStoreApi.Services;
    

Die BooksService-Klasse verwendet die folgenden MongoDB.Driver-Member, um CRUD-Vorgänge für die Datenbank auszuführen:

  • MongoClient: Liest die Serverinstanz zum Ausführen von Datenbankvorgängen. Der Konstruktor dieser Klasse wird in der MongoDB-Verbindungszeichenfolge bereitgestellt:

    public BooksService(
        IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
    {
        var mongoClient = new MongoClient(
            bookStoreDatabaseSettings.Value.ConnectionString);
    
        var mongoDatabase = mongoClient.GetDatabase(
            bookStoreDatabaseSettings.Value.DatabaseName);
    
        _booksCollection = mongoDatabase.GetCollection<Book>(
            bookStoreDatabaseSettings.Value.BooksCollectionName);
    }
    
  • IMongoDatabase: Stellt die Mongo-Datenbank zum Ausführen von Vorgängen dar. In diesem Tutorial wird die generische Methode GetCollection<TDocument>(collection) für die Schnittstelle verwendet, um Zugriff auf Daten in einer bestimmten Sammlung zu erhalten. Führen Sie CRUD-Vorgänge für die Sammlung aus, nachdem diese Methode aufgerufen wurde. Rufen Sie in der GetCollection<TDocument>(collection)-Methode folgendes auf:

    • collection steht für den Sammlungsnamen.
    • TDocument steht für den in der Sammlung gespeicherten CLR-Objekttypen.

GetCollection<TDocument>(collection) gibt ein MongoCollection-Objekt zurück, das die Sammlung darstellt. In diesem Tutorial werden die folgenden Methoden für der Sammlung aufgerufen:

  • DeleteOneAsync: Löscht ein einzelnes Dokument, das den angegebenen Suchkriterien entspricht.
  • Find<TDocument>: Gibt alle Dokumente in der Sammlung zurück, die den angegebenen Suchkriterien entsprechen.
  • InsertOneAsync: Fügt das angegebene Objekt als neues Dokument in die Sammlung ein.
  • ReplaceOneAsync: Ersetzt das einzelne Dokument, das den angegebenen Suchkriterien entspricht, durch das angegebene Objekt.

Hinzufügen eines Controllers

Fügen Sie eine BooksController-Klasse zum Verzeichnis Controller mit dem folgenden Code hinzu:

using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;

namespace BookStoreApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
    private readonly BooksService _booksService;

    public BooksController(BooksService booksService) =>
        _booksService = booksService;

    [HttpGet]
    public async Task<List<Book>> Get() =>
        await _booksService.GetAsync();

    [HttpGet("{id:length(24)}")]
    public async Task<ActionResult<Book>> Get(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        return book;
    }

    [HttpPost]
    public async Task<IActionResult> Post(Book newBook)
    {
        await _booksService.CreateAsync(newBook);

        return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
    }

    [HttpPut("{id:length(24)}")]
    public async Task<IActionResult> Update(string id, Book updatedBook)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        updatedBook.Id = book.Id;

        await _booksService.UpdateAsync(id, updatedBook);

        return NoContent();
    }

    [HttpDelete("{id:length(24)}")]
    public async Task<IActionResult> Delete(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        await _booksService.RemoveAsync(id);

        return NoContent();
    }
}

Der oben aufgeführte Web-API-Controller:

  • Verwendet die BooksService-Klasse, um CRUD-Vorgänge auszuführen.
  • Enthält Aktionsmethoden zur Unterstützung von GET-, POST-, PUT- und DELETE HTTP-Anforderungen.
  • Ruft CreatedAtAction in der Aktionsmethode Create auf, um eine HTTP 201-Antwort zurückzugeben. Der Statuscode 201 ist die Standardantwort für eine HTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. CreatedAtAction fügt der Antwort außerdem einen Location-Header hinzu. Der Location-Header gibt den URI des neu erstellten Buchs an.

Testen der Web-API

  1. Erstellen Sie die App, und führen Sie sie aus.

  2. Navigieren Sie zu https://localhost:<port>/api/books, wobei Get für die automatisch zugewiesene Portnummer für die App steht, um die parameterlose <port>-Aktionsmethode des Controllers zu testen. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    [
      {
        "id": "61a6058e6c43f32854e51f51",
        "bookName": "Design Patterns",
        "price": 54.93,
        "category": "Computers",
        "author": "Ralph Johnson"
      },
      {
        "id": "61a6058e6c43f32854e51f52",
        "bookName": "Clean Code",
        "price": 43.15,
        "category": "Computers",
        "author": "Robert C. Martin"
      }
    ]
    
  3. Wechseln Sie zu https://localhost:<port>/api/books/{id here}, um die überladene Aktionsmethode Get des Controllers zu testen. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    {
      "id": "61a6058e6c43f32854e51f52",
      "bookName": "Clean Code",
      "price": 43.15,
      "category": "Computers",
      "author": "Robert C. Martin"
    }
    

Konfigurieren von JSON-Serialisierungsoptionen

Es gibt zwei Details, die bei JSON-Antworten zu ändern sind, die im Abschnitt Testen der Web-API zurückgegeben werden:

  • Die Camel-Case-Standardschreibweise von Eigenschaftsnamen sollte so geändert werden, dass sie der Pascal-Schreibweise der Eigenschaften des CLR-Objekts entspricht.
  • Die Eigenschaft bookName sollte als Name zurückgegeben werden.

Um die zuvor genannten Anforderungen zu erfüllen, nehmen Sie die folgenden Änderungen vor:

  1. Verketten Sie in Program.cs den folgenden hervorgehobenen Code mit dem Aufruf der AddControllers-Methode:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    
    builder.Services.AddControllers()
        .AddJsonOptions(
            options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
    

    Durch die vorherige Änderung stimmen Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API mit ihren entsprechenden Eigenschaftsnamen im CLR-Objekttyp überein. Beispielsweise wird die Eigenschaft Author der Book-Klasse als Author und nicht als author serialisiert.

  2. Kommentieren Sie in Models/Book.cs die BookName-Eigenschaft mit dem [JsonPropertyName]-Attribut:

    [BsonElement("Name")]
    [JsonPropertyName("Name")]
    public string BookName { get; set; } = null!;
    

    Der Wert Name des [JsonPropertyName]-Attributs stellt den Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API dar.

  3. Fügen Sie den folgenden Code am Anfang von Models/Book.cs hinzu, um den Verweis auf das [JsonProperty]-Attribut aufzulösen:

    using System.Text.Json.Serialization;
    
  4. Wiederholen Sie die im Abschnitt Testen der Web-API definierten Schritte. Beachten Sie den Unterschied bei den JSON-Eigenschaftsnamen.

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:

Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Wichtig

Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.

Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).

Zusätzliche Ressourcen

Dieses Tutorial erstellt eine Web-API, die CRUD-Vorgänge (Create, Read, Update, Delete) für eine MongoDB-NoSQL-Datenbank durchführt.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Konfigurieren von MongoDB
  • Erstellen einer MongoDB-Datenbank
  • Definieren einer MongoDB-Sammlung und eines Schemas
  • Ausführen von MongoDB-CRUD-Vorgänge über eine Web-API
  • Anpassen der JSON-Serialisierung

Voraussetzungen

Konfigurieren von MongoDB

Ermöglichen Sie den Zugriff auf MongoDB und die Mongo DB-Shell überall auf dem Entwicklungscomputer:

  1. Unter Windows wird MongoDB standardmäßig unter C:\Programme\MongoDB installiert. Fügen Sie der Umgebungsvariablen PATH den Pfad C:\Programme\MongoDB\Server\<version_number>\bin hinzu.

  2. Laden Sie die MongoDB-Shell herunter, und wählen Sie ein Verzeichnis aus, in das sie extrahiert werden soll. Fügen Sie der PATH-Umgebungsvariablen den resultierenden Pfad für mongosh.exe hinzu.

  3. Wählen Sie auf dem Entwicklungscomputer ein Verzeichnis zum Speichern der Daten aus. Zum Beispiel C:\BooksData auf Windows. Erstellen Sie das Verzeichnis, falls es nicht vorhanden ist. Die Mongo-Shell erstellt keine neuen Verzeichnisse.

  4. Verwenden Sie in der Befehlsshell des Betriebssystems (nicht in der MongoDB-Shell) den folgenden Befehl, um eine Verbindung mit MongoDB am Standardport 27017 herzustellen. Ersetzen Sie <data_directory_path> durch das im vorherigen Schritt ausgewählte Verzeichnis.

    mongod --dbpath <data_directory_path>
    

Verwenden Sie die zuvor installierte MongoDB-Shell in den folgenden Schritten, um eine Datenbank zu erstellen, Sammlungen durchzuführen und Dokumente zu speichern. Weitere Informationen zu MongoDB-Shell-Befehlen finden Sie unter mongosh.

  1. Öffnen Sie eine Instanz der MongoDB-Befehlsshell, indem Sie mongosh.exe starten.

  2. Stellen Sie in der Befehlsshell eine Verbindung mit der Standardtestdatenbank her, indem Sie den folgenden Befehl ausführen:

    mongosh
    
  3. Führen Sie den folgenden Befehl in der Befehlsshell aus:

    use BookStore
    

    Wenn nicht bereits vorhanden, wird eine Datenbank namens BookStore erstellt. Wenn die Datenbank vorhanden ist, wird die Verbindung für Transaktionen geöffnet.

  4. Erstellen Sie eine Books-Sammlung mithilfe des folgenden Befehls:

    db.createCollection('Books')
    

    Das folgende Ergebnis wird angezeigt:

    { "ok" : 1 }
    
  5. Definieren Sie ein Schema für die Books-Sammlung. und fügen zwei Dokumente mithilfe des folgenden Befehls ein:

    db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("61a6058e6c43f32854e51f51"),
            ObjectId("61a6058e6c43f32854e51f52")
         ]
     }
    

    Hinweis

    Die im vorherigen Ergebnis angezeigten ObjectIds stimmen nicht mit denen überein, die in der Befehlsshell angezeigt werden.

  6. Zeigen Sie die Dokumente in der Datenbank mithilfe des folgenden Befehls an:

    db.Books.find().pretty()
    

    Das Ergebnis sieht in etwa wie folgt aus:

    {
         "_id" : ObjectId("61a6058e6c43f32854e51f51"),
         "Name" : "Design Patterns",
         "Price" : 54.93,
         "Category" : "Computers",
         "Author" : "Ralph Johnson"
     }
     {
         "_id" : ObjectId("61a6058e6c43f32854e51f52"),
         "Name" : "Clean Code",
         "Price" : 43.15,
         "Category" : "Computers",
         "Author" : "Robert C. Martin"
     }
    

    Das Schema fügt eine automatisch generierte _id Eigenschaft vom Typ ObjectId für jedes Dokument hinzu.

Erstellen eines ASP.NET Core-Web-API-Projektes

  1. Wechseln Sie zu Datei>Neu>Projekt.

  2. Wählen Sie den Projekttyp ASP.NET Core-Web-API aus, und klicken Sie auf Weiter.

  3. Geben Sie dem Projekt den Namen BookStoreApi, und klicken Sie auf Weiter.

  4. Wählen Sie das Framework .NET 6.0 (langfristiger Support) und dann Erstellen aus.

  5. Navigieren Sie im Fenster Paket-Manager-Konsole zum Stammverzeichnis des Projekts. Führen Sie den folgenden Befehl aus, um den .NET-Treiber für MongoDB zu installieren:

    Install-Package MongoDB.Driver
    

Hinzufügen eines Entitätsmodells

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Modelle hinzu.

  2. Fügen Sie eine Book-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BookStoreApi.Models;
    
    public class Book
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string? Id { get; set; }
    
        [BsonElement("Name")]
        public string BookName { get; set; } = null!;
    
        public decimal Price { get; set; }
    
        public string Category { get; set; } = null!;
    
        public string Author { get; set; } = null!;
    }
    

    In der obigen Klasse gilt für die Id-Eigenschaft Folgendes:

    • Sie ist erforderlich, um der MongoDB-Sammlung das CLR-Objekt (Common Language Runtime) zuzuordnen.
    • Sie wird mit [BsonId] kommentiert, um diese Eigenschaft als Primärschlüssel des Dokuments festzulegen.
    • Sie wird mit [BsonRepresentation(BsonType.ObjectId)] kommentiert, um die Übergabe des Parameters als Typ string anstelle einer ObjectId-Struktur zu ermöglichen. Mongo behandelt die Konvertierung von string zu ObjectId.

    Die Eigenschaft BookName ist mit dem Attribut [BsonElement] versehen. Der Wert Name des Attributs stellt den Eigenschaftsnamen in der MongoDB-Sammlung dar.

Hinzufügen eines Konfigurationsmodells

  1. Fügen Sie appsettings.json die folgenden Konfigurationswerte für die Datenbank hinzu:

    {
        "BookStoreDatabase": {
            "ConnectionString": "mongodb://localhost:27017",
            "DatabaseName": "BookStore",
            "BooksCollectionName": "Books"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning"
            }
        },
        "AllowedHosts": "*"
    }
    
  2. Fügen Sie eine BookStoreDatabaseSettings-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    namespace BookStoreApi.Models;
    
    public class BookStoreDatabaseSettings
    {
        public string ConnectionString { get; set; } = null!;
    
        public string DatabaseName { get; set; } = null!;
    
        public string BooksCollectionName { get; set; } = null!;
    }
    

    Mit der vorhergehenden Klasse BookStoreDatabaseSettings werden die Eigenschaftswerte BookStoreDatabase der Datei appsettings.json gespeichert. Die Namen der JSON- und der C#-Eigenschaften sind identisch, um den Zuordnungsprozess zu erleichtern.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    

    Im obigen Code wird die Konfigurationsinstanz, an die der Abschnitt BookStoreDatabase der Datei appsettings.json gebunden ist, beim DI-Container (Dependency Injection) registriert. Beispielsweise wird die Eigenschaft ConnectionString des BookStoreDatabaseSettings-Objekts mit der Eigenschaft BookStoreDatabase:ConnectionString in appsettings.json aufgefüllt.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BookStoreDatabaseSettings aufzulösen:

    using BookStoreApi.Models;
    

Hinzufügen eines CRUD-Vorgangsdiensts

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Dienste hinzu.

  2. Fügen Sie eine BooksService-Klasse zum Verzeichnis Dienste mit dem folgenden Code hinzu:

    using BookStoreApi.Models;
    using Microsoft.Extensions.Options;
    using MongoDB.Driver;
    
    namespace BookStoreApi.Services;
    
    public class BooksService
    {
        private readonly IMongoCollection<Book> _booksCollection;
    
        public BooksService(
            IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
        {
            var mongoClient = new MongoClient(
                bookStoreDatabaseSettings.Value.ConnectionString);
    
            var mongoDatabase = mongoClient.GetDatabase(
                bookStoreDatabaseSettings.Value.DatabaseName);
    
            _booksCollection = mongoDatabase.GetCollection<Book>(
                bookStoreDatabaseSettings.Value.BooksCollectionName);
        }
    
        public async Task<List<Book>> GetAsync() =>
            await _booksCollection.Find(_ => true).ToListAsync();
    
        public async Task<Book?> GetAsync(string id) =>
            await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
    
        public async Task CreateAsync(Book newBook) =>
            await _booksCollection.InsertOneAsync(newBook);
    
        public async Task UpdateAsync(string id, Book updatedBook) =>
            await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
    
        public async Task RemoveAsync(string id) =>
            await _booksCollection.DeleteOneAsync(x => x.Id == id);
    }
    

    Im vorhergehenden Code wird eine BookStoreDatabaseSettings-Instanz mittels Konstruktorinjektion über DI abgerufen. Damit kann auf die Konfigurationswerte von appsettings.json zugegriffen werden, die im Abschnitt Hinzufügen eines Konfigurationsmodells hinzugefügt wurden.

  3. Fügen Sie folgenden hervorgehobenen Code zu Program.cs hinzu:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    

    Im vorhergehenden Code wird die Klasse BooksService bei DI registriert, um die Konstruktorinjektion in verarbeitenden Klassen zu unterstützen. Die Lebensdauer des Singletondiensts ist am besten geeignet, da BooksService direkt von MongoClient abhängig ist. Gemäß den offiziellen Mongo Client-Richtlinien zur Wiederverwendung (Mongo Client reuse guidelines) sollte MongoClient bei DI mit der Lebensdauer eines Singletondiensts registriert werden.

  4. Fügen Sie den folgenden Code am Anfang von Program.cs hinzu, um den Verweis BooksService aufzulösen:

    using BookStoreApi.Services;
    

Die BooksService-Klasse verwendet die folgenden MongoDB.Driver-Member, um CRUD-Vorgänge für die Datenbank auszuführen:

  • MongoClient: Liest die Serverinstanz zum Ausführen von Datenbankvorgängen. Der Konstruktor dieser Klasse wird in der MongoDB-Verbindungszeichenfolge bereitgestellt:

    public BooksService(
        IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
    {
        var mongoClient = new MongoClient(
            bookStoreDatabaseSettings.Value.ConnectionString);
    
        var mongoDatabase = mongoClient.GetDatabase(
            bookStoreDatabaseSettings.Value.DatabaseName);
    
        _booksCollection = mongoDatabase.GetCollection<Book>(
            bookStoreDatabaseSettings.Value.BooksCollectionName);
    }
    
  • IMongoDatabase: Stellt die Mongo-Datenbank zum Ausführen von Vorgängen dar. In diesem Tutorial wird die generische Methode GetCollection<TDocument>(collection) für die Schnittstelle verwendet, um Zugriff auf Daten in einer bestimmten Sammlung zu erhalten. Führen Sie CRUD-Vorgänge für die Sammlung aus, nachdem diese Methode aufgerufen wurde. Rufen Sie in der GetCollection<TDocument>(collection)-Methode folgendes auf:

    • collection steht für den Sammlungsnamen.
    • TDocument steht für den in der Sammlung gespeicherten CLR-Objekttypen.

GetCollection<TDocument>(collection) gibt ein MongoCollection-Objekt zurück, das die Sammlung darstellt. In diesem Tutorial werden die folgenden Methoden für der Sammlung aufgerufen:

  • DeleteOneAsync: Löscht ein einzelnes Dokument, das den angegebenen Suchkriterien entspricht.
  • Find<TDocument>: Gibt alle Dokumente in der Sammlung zurück, die den angegebenen Suchkriterien entsprechen.
  • InsertOneAsync: Fügt das angegebene Objekt als neues Dokument in die Sammlung ein.
  • ReplaceOneAsync: Ersetzt das einzelne Dokument, das den angegebenen Suchkriterien entspricht, durch das angegebene Objekt.

Hinzufügen eines Controllers

Fügen Sie eine BooksController-Klasse zum Verzeichnis Controller mit dem folgenden Code hinzu:

using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;

namespace BookStoreApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
    private readonly BooksService _booksService;

    public BooksController(BooksService booksService) =>
        _booksService = booksService;

    [HttpGet]
    public async Task<List<Book>> Get() =>
        await _booksService.GetAsync();

    [HttpGet("{id:length(24)}")]
    public async Task<ActionResult<Book>> Get(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        return book;
    }

    [HttpPost]
    public async Task<IActionResult> Post(Book newBook)
    {
        await _booksService.CreateAsync(newBook);

        return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
    }

    [HttpPut("{id:length(24)}")]
    public async Task<IActionResult> Update(string id, Book updatedBook)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        updatedBook.Id = book.Id;

        await _booksService.UpdateAsync(id, updatedBook);

        return NoContent();
    }

    [HttpDelete("{id:length(24)}")]
    public async Task<IActionResult> Delete(string id)
    {
        var book = await _booksService.GetAsync(id);

        if (book is null)
        {
            return NotFound();
        }

        await _booksService.RemoveAsync(id);

        return NoContent();
    }
}

Der oben aufgeführte Web-API-Controller:

  • Verwendet die BooksService-Klasse, um CRUD-Vorgänge auszuführen.
  • Enthält Aktionsmethoden zur Unterstützung von GET-, POST-, PUT- und DELETE HTTP-Anforderungen.
  • Ruft CreatedAtAction in der Aktionsmethode Create auf, um eine HTTP 201-Antwort zurückzugeben. Der Statuscode 201 ist die Standardantwort für eine HTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. CreatedAtAction fügt der Antwort außerdem einen Location-Header hinzu. Der Location-Header gibt den URI des neu erstellten Buchs an.

Testen der Web-API

  1. Erstellen Sie die App, und führen Sie sie aus.

  2. Navigieren Sie zu https://localhost:<port>/api/books, wobei Get für die automatisch zugewiesene Portnummer für die App steht, um die parameterlose <port>-Aktionsmethode des Controllers zu testen. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    [
      {
        "id": "61a6058e6c43f32854e51f51",
        "bookName": "Design Patterns",
        "price": 54.93,
        "category": "Computers",
        "author": "Ralph Johnson"
      },
      {
        "id": "61a6058e6c43f32854e51f52",
        "bookName": "Clean Code",
        "price": 43.15,
        "category": "Computers",
        "author": "Robert C. Martin"
      }
    ]
    
  3. Wechseln Sie zu https://localhost:<port>/api/books/{id here}, um die überladene Aktionsmethode Get des Controllers zu testen. Dadurch wird eine JSON-Antwort angezeigt, die mit der folgenden Ausgabe vergleichbar ist:

    {
      "id": "61a6058e6c43f32854e51f52",
      "bookName": "Clean Code",
      "price": 43.15,
      "category": "Computers",
      "author": "Robert C. Martin"
    }
    

Konfigurieren von JSON-Serialisierungsoptionen

Es gibt zwei Details, die bei JSON-Antworten zu ändern sind, die im Abschnitt Testen der Web-API zurückgegeben werden:

  • Die Camel-Case-Standardschreibweise von Eigenschaftsnamen sollte so geändert werden, dass sie der Pascal-Schreibweise der Eigenschaften des CLR-Objekts entspricht.
  • Die Eigenschaft bookName sollte als Name zurückgegeben werden.

Um die zuvor genannten Anforderungen zu erfüllen, nehmen Sie die folgenden Änderungen vor:

  1. Verketten Sie in Program.cs den folgenden hervorgehobenen Code mit dem Aufruf der AddControllers-Methode:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.Configure<BookStoreDatabaseSettings>(
        builder.Configuration.GetSection("BookStoreDatabase"));
    
    builder.Services.AddSingleton<BooksService>();
    
    builder.Services.AddControllers()
        .AddJsonOptions(
            options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
    

    Durch die vorherige Änderung stimmen Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API mit ihren entsprechenden Eigenschaftsnamen im CLR-Objekttyp überein. Beispielsweise wird die Eigenschaft Author der Book-Klasse als Author und nicht als author serialisiert.

  2. Kommentieren Sie in Models/Book.cs die BookName-Eigenschaft mit dem [JsonPropertyName]-Attribut:

    [BsonElement("Name")]
    [JsonPropertyName("Name")]
    public string BookName { get; set; } = null!;
    

    Der Wert Name des [JsonPropertyName]-Attributs stellt den Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API dar.

  3. Fügen Sie den folgenden Code am Anfang von Models/Book.cs hinzu, um den Verweis auf das [JsonProperty]-Attribut aufzulösen:

    using System.Text.Json.Serialization;
    
  4. Wiederholen Sie die im Abschnitt Testen der Web-API definierten Schritte. Beachten Sie den Unterschied bei den JSON-Eigenschaftsnamen.

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:

Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Wichtig

Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 5.0 zu 6.0.

Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).

Zusätzliche Ressourcen

Dieses Tutorial erstellt eine Web-API, die CRUD-Vorgänge (Create, Read, Update, Delete) für eine MongoDB-NoSQL-Datenbank durchführt.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Konfigurieren von MongoDB
  • Erstellen einer MongoDB-Datenbank
  • Definieren einer MongoDB-Sammlung und eines Schemas
  • Ausführen von MongoDB-CRUD-Vorgänge über eine Web-API
  • Anpassen der JSON-Serialisierung

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Voraussetzungen

Konfigurieren von MongoDB

Wenn Sie Windows verwenden, wird MongoDB standardmäßig unter C:\Program Files\MongoDB installiert. Fügen Sie der Umgebungsvariablen Path den Pfad C:\Programme\MongoDB\Server\<version_number>\bin hinzu. Durch diese Änderung können Sie von einer beliebigen Stelle auf Ihrem Entwicklungscomputer auf MongoDB zugreifen.

Verwenden Sie die Mongo-Shell in den folgenden Schritten, um eine Datenbank zu erstellen, Sammlungen durchzuführen und Dokumente zu speichern. Weitere Informationen zu Mongo-Shell-Befehlen finden Sie unter Arbeiten mit der Mongo-Shell.

  1. Wählen Sie ein Verzeichnis auf Ihrem Entwicklungscomputer zum Speichern der Daten. Zum Beispiel C:\BooksData auf Windows. Erstellen Sie das Verzeichnis, falls es nicht vorhanden ist. Die Mongo-Shell erstellt keine neuen Verzeichnisse.

  2. Öffnen Sie eine Befehlsshell. Führen Sie den folgenden Befehl aus, um eine Verbindung zu MongoDB auf dem Standardport 27017 herzustellen. Denken Sie daran, <data_directory_path> durch das Verzeichnis zu ersetzen, das Sie im vorherigen Schritt gewählt haben.

    mongod --dbpath <data_directory_path>
    
  3. Öffnen Sie eine andere Befehlsshellinstanz. Verbinden Sie sich mit der Standardtestdatenbank, indem Sie den folgenden Befehl ausführen:

    mongo
    
  4. Führen Sie den folgenden Befehl in einer Befehlsshell aus:

    use BookstoreDb
    

    Wenn nicht bereits vorhanden, wird eine Datenbank namens BookstoreDb erstellt. Wenn die Datenbank vorhanden ist, wird die Verbindung für Transaktionen geöffnet.

  5. Erstellen Sie eine Books-Sammlung mithilfe des folgenden Befehls:

    db.createCollection('Books')
    

    Das folgende Ergebnis wird angezeigt:

    { "ok" : 1 }
    
  6. Definieren Sie ein Schema für die Books-Sammlung. und fügen zwei Dokumente mithilfe des folgenden Befehls ein:

    db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson'}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin'}])
    

    Das folgende Ergebnis wird angezeigt:

    {
      "acknowledged" : true,
      "insertedIds" : [
        ObjectId("5bfd996f7b8e48dc15ff215d"),
        ObjectId("5bfd996f7b8e48dc15ff215e")
      ]
    }
    

    Hinweis

    Beim Ausführen dieses Beispiels stimmen die in diesem Artikel angezeigten IDs nicht mit den IDs überein.

  7. Zeigen Sie die Dokumente in der Datenbank mithilfe des folgenden Befehls an:

    db.Books.find({}).pretty()
    

    Das folgende Ergebnis wird angezeigt:

    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215d"),
      "Name" : "Design Patterns",
      "Price" : 54.93,
      "Category" : "Computers",
      "Author" : "Ralph Johnson"
    }
    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215e"),
      "Name" : "Clean Code",
      "Price" : 43.15,
      "Category" : "Computers",
      "Author" : "Robert C. Martin"
    }
    

    Das Schema fügt eine automatisch generierte _id Eigenschaft vom Typ ObjectId für jedes Dokument hinzu.

Die Datenbank ist bereit. Sie können beginnen, die ASP.NET Core-Web-API zu erstellen.

Erstellen eines ASP.NET Core-Web-API-Projektes

  1. Wechseln Sie zu Datei>Neu>Projekt.

  2. Wählen Sie den Projekttyp ASP.NET Core-Webanwendung aus, und klicken Sie auf Weiter.

  3. Geben Sie dem Projekt den Namen BooksApi, und klicken Sie auf Erstellen.

  4. Wählen Sie das .NET Core-Zielframework und ASP.NET Core 3.0 aus. Wählen Sie die Projektvorlage API aus, und klicken Sie auf Erstellen.

  5. Besuchen Sie den NuGet-Katalog: MongoDB.Driver, um die neueste stabile Version des .NET-Treibers für MongoDB zu ermitteln. Navigieren Sie im Fenster Paket-Manager-Konsole zum Stammverzeichnis des Projekts. Führen Sie den folgenden Befehl aus, um den .NET-Treiber für MongoDB zu installieren:

    Install-Package MongoDB.Driver -Version {VERSION}
    

Hinzufügen eines Entitätsmodells

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Modelle hinzu.

  2. Fügen Sie eine Book-Klasse zum Verzeichnis Modelle mit dem folgenden Code hinzu:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BooksApi.Models
    {
        public class Book
        {
            [BsonId]
            [BsonRepresentation(BsonType.ObjectId)]
            public string Id { get; set; }
    
            [BsonElement("Name")]
            public string BookName { get; set; }
    
            public decimal Price { get; set; }
    
            public string Category { get; set; }
    
            public string Author { get; set; }
        }
    }
    

    In der obigen Klasse gilt für die Id-Eigenschaft Folgendes:

    • Sie ist erforderlich, um der MongoDB-Sammlung das CLR-Objekt (Common Language Runtime) zuzuordnen.
    • Sie wird mit [BsonId] kommentiert, um diese Eigenschaft als Primärschlüssel des Dokuments festzulegen.
    • Sie wird mit [BsonRepresentation(BsonType.ObjectId)] kommentiert, um die Übergabe des Parameters als Typ string anstelle einer ObjectId-Struktur zu ermöglichen. Mongo behandelt die Konvertierung von string zu ObjectId.

    Die Eigenschaft BookName ist mit dem Attribut [BsonElement] versehen. Der Wert Name des Attributs stellt den Eigenschaftsnamen in der MongoDB-Sammlung dar.

Hinzufügen eines Konfigurationsmodells

  1. Fügen Sie appsettings.json die folgenden Konfigurationswerte für die Datenbank hinzu:

    {
      "BookstoreDatabaseSettings": {
        "BooksCollectionName": "Books",
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookstoreDb"
      },
      "Logging": {
        "IncludeScopes": false,
        "Debug": {
          "LogLevel": {
            "Default": "Warning"
          }
        },
        "Console": {
          "LogLevel": {
            "Default": "Warning"
          }
        }
      }
    }
    
  2. Fügen Sie mit dem folgenden Code dem Verzeichnis BookstoreDatabaseSettings.cs die Datei BookstoreDatabaseSettings.cs hinzu:

    namespace BooksApi.Models
    {
        public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings
        {
            public string BooksCollectionName { get; set; }
            public string ConnectionString { get; set; }
            public string DatabaseName { get; set; }
        }
    
        public interface IBookstoreDatabaseSettings
        {
            string BooksCollectionName { get; set; }
            string ConnectionString { get; set; }
            string DatabaseName { get; set; }
        }
    }
    

    Mit der vorhergehenden Klasse BookstoreDatabaseSettings werden die Eigenschaftswerte BookstoreDatabaseSettings der Datei appsettings.json gespeichert. Die Namen der JSON- und der C#-Eigenschaften sind identisch, um den Zuordnungsprozess zu erleichtern.

  3. Fügen Sie folgenden hervorgehobenen Code zu Startup.ConfigureServices hinzu:

    public void ConfigureServices(IServiceCollection services)
    {
        // requires using Microsoft.Extensions.Options
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddControllers();
    }
    

    Für den Code oben gilt:

    • Die Konfigurationsinstanz, an die der Abschnitt BookstoreDatabaseSettings der Datei appsettings.json gebunden ist, ist beim Dependency-Injection-Container registriert. Dies bedeutet, dass die Eigenschaft ConnectionString eines BookstoreDatabaseSettings-Objekts beispielsweise mit der Eigenschaft BookstoreDatabaseSettings:ConnectionString in appsettings.json aufgefüllt wird.
    • Die Schnittstelle IBookstoreDatabaseSettings ist bei DI mit der Lebensdauer eines Singletondiensts registriert. Beim Einfügen wird die Schnittstelleninstanz in ein BookstoreDatabaseSettings-Objekt aufgelöst.
  4. Fügen Sie den folgenden Code am Anfang von Startup.cs hinzu, um die BookstoreDatabaseSettings- und IBookstoreDatabaseSettings-Verweise aufzulösen:

    using BooksApi.Models;
    

Hinzufügen eines CRUD-Vorgangsdiensts

  1. Fügen Sie zum Stammverzeichnis des Projekts ein Verzeichnis Dienste hinzu.

  2. Fügen Sie eine BookService-Klasse zum Verzeichnis Dienste mit dem folgenden Code hinzu:

    using BooksApi.Models;
    using MongoDB.Driver;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace BooksApi.Services
    {
        public class BookService
        {
            private readonly IMongoCollection<Book> _books;
    
            public BookService(IBookstoreDatabaseSettings settings)
            {
                var client = new MongoClient(settings.ConnectionString);
                var database = client.GetDatabase(settings.DatabaseName);
    
                _books = database.GetCollection<Book>(settings.BooksCollectionName);
            }
    
            public List<Book> Get() =>
                _books.Find(book => true).ToList();
    
            public Book Get(string id) =>
                _books.Find<Book>(book => book.Id == id).FirstOrDefault();
    
            public Book Create(Book book)
            {
                _books.InsertOne(book);
                return book;
            }
    
            public void Update(string id, Book bookIn) =>
                _books.ReplaceOne(book => book.Id == id, bookIn);
    
            public void Remove(Book bookIn) =>
                _books.DeleteOne(book => book.Id == bookIn.Id);
    
            public void Remove(string id) => 
                _books.DeleteOne(book => book.Id == id);
        }
    }
    

    Im vorhergehenden Code wird eine IBookstoreDatabaseSettings-Instanz mittels Konstruktorinjektion über DI abgerufen. Damit kann auf die Konfigurationswerte von appsettings.json zugegriffen werden, die im Abschnitt Hinzufügen eines Konfigurationsmodells hinzugefügt wurden.

  3. Fügen Sie folgenden hervorgehobenen Code zu Startup.ConfigureServices hinzu:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddControllers();
    }
    

    Im vorhergehenden Code wird die Klasse BookService bei DI registriert, um die Konstruktorinjektion in verarbeitenden Klassen zu unterstützen. Die Lebensdauer des Singletondiensts ist am besten geeignet, da BookService direkt von MongoClient abhängig ist. Gemäß den offiziellen Mongo Client-Richtlinien zur Wiederverwendung (Mongo Client reuse guidelines) sollte MongoClient bei DI mit der Lebensdauer eines Singletondiensts registriert werden.

  4. Fügen Sie den folgenden Code am Anfang von Startup.cs hinzu, um den Verweis BookService aufzulösen:

    using BooksApi.Services;
    

Die BookService-Klasse verwendet die folgenden MongoDB.Driver-Member, um CRUD-Vorgänge für die Datenbank auszuführen:

  • MongoClient: Liest die Serverinstanz zum Ausführen von Datenbankvorgängen. Der Konstruktor dieser Klasse wird in der MongoDB-Verbindungszeichenfolge bereitgestellt:

    public BookService(IBookstoreDatabaseSettings settings)
    {
        var client = new MongoClient(settings.ConnectionString);
        var database = client.GetDatabase(settings.DatabaseName);
    
        _books = database.GetCollection<Book>(settings.BooksCollectionName);
    }
    
  • IMongoDatabase: Stellt die Mongo-Datenbank zum Ausführen von Vorgängen dar. In diesem Tutorial wird die generische Methode GetCollection<TDocument>(collection) für die Schnittstelle verwendet, um Zugriff auf Daten in einer bestimmten Sammlung zu erhalten. Führen Sie CRUD-Vorgänge für die Sammlung aus, nachdem diese Methode aufgerufen wurde. Rufen Sie in der GetCollection<TDocument>(collection)-Methode folgendes auf:

    • collection steht für den Sammlungsnamen.
    • TDocument steht für den in der Sammlung gespeicherten CLR-Objekttypen.

GetCollection<TDocument>(collection) gibt ein MongoCollection-Objekt zurück, das die Sammlung darstellt. In diesem Tutorial werden die folgenden Methoden für der Sammlung aufgerufen:

  • DeleteOne: Löscht das Einzeldokument, das den angegebenen Suchkriterien entspricht.
  • Find<TDocument>: Gibt alle Dokumente in der Sammlung zurück, die den angegebenen Suchkriterien entsprechen.
  • InsertOne: Fügt das angegebene Objekt als neues Dokument in die Sammlung ein.
  • ReplaceOne: Ersetzt das Einzeldokument, das den angegebenen Suchkriterien entspricht, durch das angegebene Objekt.

Hinzufügen eines Controllers

Fügen Sie eine BooksController-Klasse zum Verzeichnis Controller mit dem folgenden Code hinzu:

using BooksApi.Models;
using BooksApi.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace BooksApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BooksController : ControllerBase
    {
        private readonly BookService _bookService;

        public BooksController(BookService bookService)
        {
            _bookService = bookService;
        }

        [HttpGet]
        public ActionResult<List<Book>> Get() =>
            _bookService.Get();

        [HttpGet("{id:length(24)}", Name = "GetBook")]
        public ActionResult<Book> Get(string id)
        {
            var book = _bookService.Get(id);

            if (book == null)
            {
                return NotFound();
            }

            return book;
        }

        [HttpPost]
        public ActionResult<Book> Create(Book book)
        {
            _bookService.Create(book);

            return CreatedAtRoute("GetBook", new { id = book.Id.ToString() }, book);
        }

        [HttpPut("{id:length(24)}")]
        public IActionResult Update(string id, Book bookIn)
        {
            var book = _bookService.Get(id);

            if (book == null)
            {
                return NotFound();
            }

            _bookService.Update(id, bookIn);

            return NoContent();
        }

        [HttpDelete("{id:length(24)}")]
        public IActionResult Delete(string id)
        {
            var book = _bookService.Get(id);

            if (book == null)
            {
                return NotFound();
            }

            _bookService.Remove(id);

            return NoContent();
        }
    }
}

Der oben aufgeführte Web-API-Controller:

  • Verwendet die BookService-Klasse, um CRUD-Vorgänge auszuführen.
  • Enthält Aktionsmethoden zur Unterstützung von GET-, POST-, PUT- und DELETE HTTP-Anforderungen.
  • Ruft CreatedAtRoute in der Aktionsmethode Create auf, um eine HTTP 201-Antwort zurückzugeben. Der Statuscode 201 ist die Standardantwort für eine HTTP POST-Methode, die eine neue Ressource auf dem Server erstellt. CreatedAtRoute fügt der Antwort außerdem einen Location-Header hinzu. Der Location-Header gibt den URI des neu erstellten Buchs an.

Testen der Web-API

  1. Erstellen Sie die App, und führen Sie sie aus.

  2. Wechseln Sie zu https://localhost:<port>/api/books, um die parameterlose Aktionsmethode Get des Controllers zu testen. Die folgende JSON-Antwort wird angezeigt:

    [
      {
        "id":"5bfd996f7b8e48dc15ff215d",
        "bookName":"Design Patterns",
        "price":54.93,
        "category":"Computers",
        "author":"Ralph Johnson"
      },
      {
        "id":"5bfd996f7b8e48dc15ff215e",
        "bookName":"Clean Code",
        "price":43.15,
        "category":"Computers",
        "author":"Robert C. Martin"
      }
    ]
    
  3. Wechseln Sie zu https://localhost:<port>/api/books/{id here}, um die überladene Aktionsmethode Get des Controllers zu testen. Die folgende JSON-Antwort wird angezeigt:

    {
      "id":"{ID}",
      "bookName":"Clean Code",
      "price":43.15,
      "category":"Computers",
      "author":"Robert C. Martin"
    }
    

Konfigurieren von JSON-Serialisierungsoptionen

Es gibt zwei Details, die bei JSON-Antworten zu ändern sind, die im Abschnitt Testen der Web-API zurückgegeben werden:

  • Die Camel-Case-Standardschreibweise von Eigenschaftsnamen sollte so geändert werden, dass sie der Pascal-Schreibweise der Eigenschaften des CLR-Objekts entspricht.
  • Die Eigenschaft bookName sollte als Name zurückgegeben werden.

Um die zuvor genannten Anforderungen zu erfüllen, nehmen Sie die folgenden Änderungen vor:

  1. JSON.NET wurde aus dem freigegebenen ASP.NET-Framework entfernt. Fügen Sie Microsoft.AspNetCore.Mvc.NewtonsoftJson einen Paketverweis hinzu.

  2. Verketten Sie in Startup.ConfigureServices den folgenden hervorgehobenen Code mit dem Aufruf der AddControllers-Methode:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddControllers()
            .AddNewtonsoftJson(options => options.UseMemberCasing());
    }
    

    Durch die vorherige Änderung stimmen Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API mit ihren entsprechenden Eigenschaftsnamen im CLR-Objekttyp überein. Beispielsweise wird die Eigenschaft Author der Book-Klasse als Author serialisiert.

  3. Versehen Sie in Models/Book.cs die BookName-Eigenschaft mit dem folgenden [JsonProperty]-Attribut:

    [BsonElement("Name")]
    [JsonProperty("Name")]
    public string BookName { get; set; }
    

    Der Wert Name des [JsonProperty]-Attributs stellt den Eigenschaftsnamen in der serialisierten JSON-Antwort der Web-API dar.

  4. Fügen Sie den folgenden Code am Anfang von Models/Book.cs hinzu, um den Verweis auf das [JsonProperty]-Attribut aufzulösen:

    using Newtonsoft.Json;
    
  5. Wiederholen Sie die im Abschnitt Testen der Web-API definierten Schritte. Beachten Sie den Unterschied bei den JSON-Eigenschaftsnamen.

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:

Duende IdentityServer ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende IdentityServer ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Weitere Informationen finden Sie in der Übersicht über Duende IdentityServer.

Weitere Informationen zu anderen Authentifizierungsanbietern finden Sie unter Community-basierte OSS-Authentifizierungsoptionen für ASP.NET Core.

Nächste Schritte

Weitere Informationen zum Erstellen von ASP.NET-Core Web-APIs finden Sie in den folgenden Ressourcen: