Udostępnij za pośrednictwem


Tworzenie internetowego interfejsu API przy użyciu platformy ASP.NET Core i bazy danych MongoDB

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję artykułu .NET 9 .

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z bieżącą wersją, zobacz wersję artykułu .NET 9 .

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zobacz wersję artykułu .NET 9 .

Przez Pratik Khandelwal i Scott Addie

W tym samouczku tworzony jest webowy interfejs API, który wykonuje operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL MongoDB.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Konfigurowanie bazy danych MongoDB
  • Tworzenie bazy danych MongoDB
  • Definiowanie kolekcji i schematu bazy danych MongoDB
  • Wykonywanie operacji CRUD bazy danych MongoDB z internetowego interfejsu API
  • Dostosowywanie serializacji JSON

Wymagania wstępne

Konfigurowanie bazy danych MongoDB

Włącz dostęp do MongoDB i MongoDB Shell z dowolnego miejsca na komputerze programistycznym (Windows/Linux/macOS):

  1. Pobierz i zainstaluj powłokę MongoDB

    • macOS/Linux: Wybierz katalog, do którego chcesz wyodrębnić powłokę MongoDB. Dodaj wynikową ścieżkę dla mongosh do zmiennej środowiskowej PATH.
    • Windows: MongoDB Shell (mongosh.exe) jest zainstalowany w C:\Users\<user>\AppData\Local\Programs\mongosh. Dodaj wynikową ścieżkę dla mongosh.exe do zmiennej środowiskowej PATH.
  2. Pobierz i zainstaluj bazę danych MongoDB:

    • macOS/Linux: sprawdź katalog, w którym zainstalowano bazę danych MongoDB, zwykle w katalogu /usr/local/mongodb. Dodaj wynikową ścieżkę dla mongodb do zmiennej środowiskowej PATH.
    • Windows: baza danych MongoDB jest instalowana domyślnie w folderze C:\Program Files\MongoDB . Dodaj C:\Program Files\MongoDB\Server\<version_number>\bin do zmiennej środowiskowej PATH .
  3. Wybierz katalog magazynu danych: wybierz katalog na maszynie programistycznej do przechowywania danych. Utwórz katalog, jeśli nie istnieje. Powłoka bazy danych MongoDB nie tworzy nowych katalogów:

    • macOS/Linux: na przykład /usr/local/var/mongodb.
    • Windows: na przykład C:\\BooksData.
  4. W powłoce poleceń systemu operacyjnego (a nie w powłoce bazy danych MongoDB) użyj następującego polecenia, aby nawiązać połączenie z bazą danych MongoDB na domyślnym porcie 27017. Zastąp <data_directory_path> element katalogiem wybranym w poprzednim kroku.

    mongod --dbpath <data_directory_path>
    

Użyj wcześniej zainstalowanej powłoki MongoDB w poniższych krokach, aby utworzyć bazę danych, stworzyć kolekcje i zarchiwizować dokumenty. Aby uzyskać więcej informacji na temat poleceń powłoki bazy danych MongoDB, zobacz mongosh.

  1. Otwórz wystąpienie powłoki poleceń bazy danych MongoDB, uruchamiając mongosh.exe lub poprzez wpisanie następującego polecenia w powłoce poleceń:

    mongosh
    
  2. W powłoce poleceń połącz się z domyślną bazą danych testowych, uruchamiając polecenie:

    use BookStore
    

    Baza danych o nazwie BookStore jest tworzona, jeśli jeszcze nie istnieje. Jeśli baza danych istnieje, jego połączenie jest otwarte dla transakcji.

  3. Books Utwórz kolekcję przy użyciu następującego polecenia:

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  4. Zdefiniuj schemat kolekcji Books i wstaw dwa dokumenty przy użyciu następującego polecenia:

    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" }])
    

    Zostanie wyświetlony wynik podobny do następującego:

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

    Uwaga

    Wartości ObjectIdpokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.

  5. Wyświetl dokumenty w bazie danych przy użyciu następującego polecenia:

    db.Books.find().pretty()
    

    Zostanie wyświetlony wynik podobny do następującego:

    {
         "_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"
     }
    

    Schemat dodaje automatycznie wygenerowaną _id właściwość typu ObjectId dla każdego dokumentu.

Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

  1. Przejdź do Plik>Nowy>Projekt.
  2. Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.
  3. Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.
  4. W oknie dialogowym Dodatkowe informacje:
  • Upewnij się, że platforma jest .NET 9.0 (Standardowe wsparcie).
  • Upewnij się, że pole wyboru Użyj kontrolerów jest zaznaczone.
  • Upewnij się, że zaznaczono pole wyboru Włącz obsługę interfejsu OpenAPI.
  • Wybierz Utwórz.
  1. W oknie Konsoli Menedżera pakietów przejdź do katalogu głównego projektu. Uruchom następujące polecenie, aby zainstalować sterownik platformy .NET dla bazy danych MongoDB:

    Install-Package MongoDB.Driver
    

Dodawanie modelu jednostki

  1. Dodaj katalog Models do katalogu głównego projektu.

  2. Dodaj klasę Book do katalogu Models przy użyciu następującego kodu:

    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!;
    }
    

    W poprzedniej klasie właściwość Id jest:

    • Wymagane do mapowania obiektu Common Language Runtime (CLR) na kolekcję MongoDB.
    • Dodaj adnotację , [BsonId] aby ustawić tę właściwość jako klucz podstawowy dokumentu.
    • Adnotacje z parametrem [BsonRepresentation(BsonType.ObjectId)] umożliwiają przekazywanie parametru jako typu string zamiast struktury ObjectId . Mongo obsługuje konwersję z string na ObjectId.

    Właściwość BookName jest oznaczona adnotacją z atrybutem [BsonElement] . Wartość atrybutu Name reprezentuje nazwę właściwości w kolekcji MongoDB.

Dodawanie modelu konfiguracji

  1. Dodaj następujące wartości konfiguracji bazy danych do :appsettings.json

    {
      "BookStoreDatabase": {
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookStore",
        "BooksCollectionName": "Books"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    
  2. Dodaj klasę BookStoreDatabaseSettings do katalogu Models przy użyciu następującego kodu:

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

    Poprzednia BookStoreDatabaseSettings klasa służy do przechowywania appsettings.json wartości właściwości pliku BookStoreDatabase . Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie instancja konfiguracji, do której wiąże się sekcja pliku appsettings.json, jest zarejestrowana w kontenerze Dependency Injection (DI). Na przykład właściwość obiektu BookStoreDatabaseSettings jest wypełniana właściwością ConnectionString w BookStoreDatabase:ConnectionString.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BookStoreDatabaseSettings.

    using BookStoreApi.Models;
    

Dodaj usługę operacji CRUD

  1. Dodaj katalog Services do katalogu głównego projektu.

  2. Dodaj klasę BooksService do katalogu Services za pomocą następującego kodu:

    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);
    }
    

    W poprzednim kodzie instancja BookStoreDatabaseSettings jest pobierana z DI za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie klasa BooksService jest zarejestrowana w DI w celu obsługi wstrzykiwania konstruktora w klasach korzystających. Jednostkowy okres istnienia usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClient. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB, MongoClient należy zarejestrować w DI z czasem życia singletona.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BooksService.

    using BookStoreApi.Services;
    

Klasa BooksService używa następujących MongoDB.Driver elementów członkowskich do uruchamiania operacji CRUD względem bazy danych:

  • MongoClient: pobiera instancję serwera do wykonywania operacji na bazie danych. Konstruktor tej klasy jest udostępniany w parametry połączenia bazy danych MongoDB:

    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: reprezentuje bazę danych Mongo do uruchamiania operacji. W tym samouczku użyto ogólnej metody GetCollection<TDocument>(collection) w interfejsie, aby uzyskać dostęp do danych w określonej kolekcji. Uruchom operacje CRUD względem kolekcji po wywołaniu tej metody. W wywołaniu GetCollection<TDocument>(collection) metody:

    • collection reprezentuje nazwę kolekcji.
    • TDocument reprezentuje typ obiektu CLR przechowywany w kolekcji.

GetCollection<TDocument>(collection) Zwraca obiekt MongoCollection reprezentujący kolekcję. W tym samouczku następujące metody są wywoływane w kolekcji:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<TDocument>: Zwraca wszystkie dokumenty w kolekcji, które pasują do podanych kryteriów wyszukiwania.
  • InsertOneAsync: wstawia podany obiekt jako nowy dokument w kolekcji.
  • ReplaceOneAsync: zastępuje pojedynczy dokument pasujący do podanych kryteriów wyszukiwania podanym obiektem.

Dodawanie kontrolera

Dodaj klasę BooksController do katalogu Controllers z następującym kodem:

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();
    }
}

Poprzedni kontroler internetowego interfejsu API:

  • Używa klasy do uruchamiania operacji CRUD BooksService.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction w metodzie akcji Create, aby zwrócić odpowiedź HTTP 201. Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction również dodaje nagłówek Location do odpowiedzi. Nagłówek Location wskazuje URI nowo utworzonej książki.

Konfigurowanie opcji serializacji JSON

Istnieją dwa szczegóły dotyczące odpowiedzi JSON zwróconych w sekcji Testowanie internetowego interfejsu API :

  • Domyślne formatowanie nazw właściwości w stylu camel case powinno zostać zmienione, aby odpowiadało stylowi Pascal w nazwach właściwości obiektu CLR.
  • Właściwość bookName powinna zostać zwrócona jako Name.

Aby spełnić powyższe wymagania, wprowadź następujące zmiany:

  1. W Program.cs, dołącz następujący wyróżniony kod do wywołania metody AddControllers.

    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);
    

    Po powyższej zmianie nazwy właściwości w serializowanej odpowiedzi JSON interfejsu API sieci Web są zgodne z odpowiednimi nazwami właściwości w typie obiektu CLR. Na przykład właściwość Book klasy Author serializuje się jako Author zamiast author.

  2. W Models/Book.cspliku dodaj adnotację do BookName właściwości za pomocą atrybutu [JsonPropertyName] :

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

    Wartość [JsonPropertyName] atrybutu Name reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.

  3. Dodaj następujący kod na początku Models/Book.cs , aby rozwiązać odwołanie do atrybutu [JsonProperty]:

    using System.Text.Json.Serialization;
    
  4. Powtórz kroki zdefiniowane w sekcji Testowanie internetowego interfejsu API . Zwróć uwagę na różnicę w nazwach właściwości JSON.

Przetestuj internetowy interfejs API

W tym samouczku używamy Endpoints Explorer i plików .http do testowania interfejsu API.

  1. Skompiluj i uruchom aplikację.

  2. W Eksploratorze punktów końcowych kliknij prawym przyciskiem myszy pierwszy punkt końcowy /api/books, a następnie wybierz pozycję Generuj żądanie.

    Do pliku zostanie dodana następująca BookStoreApi.http zawartość. Jeśli jest to pierwszy raz, gdy zostanie wygenerowane żądanie, plik zostanie utworzony w katalogu głównym projektu.

    @BookStoreApi_HostAddress = https://localhost:<port>
    
    GET {{BookStoreApi_HostAddress}}/api/books
    
    ###
    

    Numer portu powinien być już ustawiony na port używany przez aplikację, na przykład https://localhost:56874. Jeśli tak nie jest, możesz znaleźć numer portu w oknie danych wyjściowych podczas uruchamiania aplikacji.

  3. Wybierz link Wyślij żądanie powyżej nowego GET wiersza żądania.

    Żądanie GET jest wysyłane do aplikacji, a odpowiedź jest wyświetlana w okienku Odpowiedź .

  4. Ciało odpowiedzi pokazuje wynik JSON zawierający rekordy książek podobne do następujących:

    [
      {
        "Id": "61a6058e6c43f32854e51f51",
        "Name": "Design Patterns",
        "Price": 54.93,
        "Category": "Computers",
        "Author": "Ralph Johnson"
      },
      {
        "Id": "61a6058e6c43f32854e51f52",
        "Name": "Clean Code",
        "Price": 43.15,
        "Category": "Computers",
        "Author": "Robert C. Martin"
      }
    ]
    
  5. Aby pobrać pojedynczą książkę, kliknij prawym przyciskiem myszy /api/books/{id}, params (string id) punkt końcowy GET w Eksploratorze punktów końcowych i wybierz polecenie Generuj żądanie.

    Następująca zawartość jest dołączana do BookStoreApi.http pliku:

    @id=string
    GET {{BookStoreApi_HostAddress}}/api/books/{{id}}
    
    ###
    
  6. Zastąp id zmienną jednym z identyfikatorów zwróconych z wcześniejszego żądania, na przykład:

    @id="61a6058e6c43f32854e51f52"
    GET {{BookStoreApi_HostAddress}}/api/books/{{id}}
    
    ###
    
  7. Wybierz link Wyślij żądanie powyżej nowego GET wiersza żądania.

    Żądanie GET jest wysyłane do aplikacji, a odpowiedź jest wyświetlana w okienku Odpowiedź .

  8. Treść odpowiedzi zawiera kod JSON podobny do następującego:

    {
      "Id": "61a6058e6c43f32854e51f52",
      "Name": "Clean Code",
      "Price": 43.15,
      "Category": "Computers",
      "Author": "Robert C. Martin"
    }
    
  9. Aby przetestować punkt końcowy POST, kliknij prawym przyciskiem myszy /api/books punkt końcowy POST i wybierz polecenie Generuj żądanie.

    Do pliku zostanie dodana następująca BookStoreApi.http zawartość:

    POST {{BookStoreApi_HostAddress}}/api/books
    Content-Type: application/json
    
    {
      //Book
    }
    
    ###
    
  10. Zastąp komentarz książki obiektem książki jako treścią żądania JSON:

    POST {{BookStoreApi_HostAddress}}/api/books
    Content-Type: application/json
    
     {
       "Name": "The Pragmatic Programmer",
       "Price": 49.99,
       "Category": "Computers",
       "Author": "Andy Hunt"
     }
    
    ###
    
  11. Wybierz link Wyślij żądanie powyżej POST wiersza żądania.

    Żądanie POST jest wysyłane do aplikacji, a odpowiedź jest wyświetlana w okienku Odpowiedź . Odpowiedź powinna zawierać nowo utworzoną książkę z przypisanym identyfikatorem.

  12. Na koniec, aby usunąć książkę, kliknij prawym przyciskiem myszy /api/books/{id}, params (string id) punkt końcowy DELETE i wybierz polecenie Generuj żądanie.

    Następująca zawartość jest dołączana do BookStoreApi.http pliku:

    DELETE {{BookStoreApi_HostAddress}}/api/Books/{{id}}
    
    ###
    
  13. Zastąp zmienną id jednym z identyfikatorów zwróconych z wcześniejszego żądania, a następnie kliknij pozycję Wyślij żądanie. Przykład:

    DELETE {{BookStoreApi_HostAddress}}/api/Books/67f417517ce1b36aeab71236
    
    ###
    

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć webowe interfejsy API i SPA, użyj jednego z następujących rozwiązań:

Duende Identity Server to struktura OpenID Connect i OAuth 2.0 dla ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Dodatkowe zasoby

W tym samouczku tworzony jest webowy interfejs API, który wykonuje operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL MongoDB.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Konfigurowanie bazy danych MongoDB
  • Tworzenie bazy danych MongoDB
  • Definiowanie kolekcji i schematu bazy danych MongoDB
  • Wykonywanie operacji CRUD bazy danych MongoDB z internetowego interfejsu API
  • Dostosowywanie serializacji JSON

Wymagania wstępne

Konfigurowanie bazy danych MongoDB

Włącz dostęp do MongoDB i MongoDB Shell z dowolnego miejsca na komputerze programistycznym (Windows/Linux/macOS):

  1. Pobierz i zainstaluj powłokę MongoDB

    • macOS/Linux: Wybierz katalog, do którego chcesz wyodrębnić powłokę MongoDB. Dodaj wynikową ścieżkę dla mongosh do zmiennej środowiskowej PATH.
    • Windows: MongoDB Shell (mongosh.exe) jest zainstalowany w C:\Users\<user>\AppData\Local\Programs\mongosh. Dodaj wynikową ścieżkę dla mongosh.exe do zmiennej środowiskowej PATH.
  2. Pobierz i zainstaluj bazę danych MongoDB:

    • macOS/Linux: sprawdź katalog, w którym zainstalowano bazę danych MongoDB, zwykle w katalogu /usr/local/mongodb. Dodaj wynikową ścieżkę dla mongodb do zmiennej środowiskowej PATH.
    • Windows: baza danych MongoDB jest instalowana domyślnie w folderze C:\Program Files\MongoDB . Dodaj C:\Program Files\MongoDB\Server\<version_number>\bin do zmiennej środowiskowej PATH .
  3. Wybierz katalog magazynu danych: wybierz katalog na maszynie programistycznej do przechowywania danych. Utwórz katalog, jeśli nie istnieje. Powłoka bazy danych MongoDB nie tworzy nowych katalogów:

    • macOS/Linux: na przykład /usr/local/var/mongodb.
    • Windows: na przykład C:\\BooksData.
  4. W powłoce poleceń systemu operacyjnego (a nie w powłoce bazy danych MongoDB) użyj następującego polecenia, aby nawiązać połączenie z bazą danych MongoDB na domyślnym porcie 27017. Zastąp <data_directory_path> element katalogiem wybranym w poprzednim kroku.

    mongod --dbpath <data_directory_path>
    

Użyj wcześniej zainstalowanej powłoki MongoDB w poniższych krokach, aby utworzyć bazę danych, stworzyć kolekcje i zarchiwizować dokumenty. Aby uzyskać więcej informacji na temat poleceń powłoki bazy danych MongoDB, zobacz mongosh.

  1. Otwórz wystąpienie powłoki poleceń bazy danych MongoDB, uruchamiając mongosh.exe lub poprzez wpisanie następującego polecenia w powłoce poleceń:

    mongosh
    
  2. W powłoce poleceń połącz się z domyślną bazą danych testowych, uruchamiając polecenie:

    use BookStore
    

    Baza danych o nazwie BookStore jest tworzona, jeśli jeszcze nie istnieje. Jeśli baza danych istnieje, jego połączenie jest otwarte dla transakcji.

  3. Books Utwórz kolekcję przy użyciu następującego polecenia:

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  4. Zdefiniuj schemat kolekcji Books i wstaw dwa dokumenty przy użyciu następującego polecenia:

    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" }])
    

    Zostanie wyświetlony wynik podobny do następującego:

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

    Uwaga

    Wartości ObjectIdpokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.

  5. Wyświetl dokumenty w bazie danych przy użyciu następującego polecenia:

    db.Books.find().pretty()
    

    Zostanie wyświetlony wynik podobny do następującego:

    {
         "_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"
     }
    

    Schemat dodaje automatycznie wygenerowaną _id właściwość typu ObjectId dla każdego dokumentu.

Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

  1. Przejdź do Plik>Nowy>Projekt.

  2. Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.

  3. Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.

  4. Wybierz platformę .NET 8.0 (obsługa długoterminowa) i wybierz pozycję Utwórz.

  5. W oknie Konsoli Menedżera pakietów przejdź do katalogu głównego projektu. Uruchom następujące polecenie, aby zainstalować sterownik platformy .NET dla bazy danych MongoDB:

    Install-Package MongoDB.Driver
    

Dodawanie modelu jednostki

  1. Dodaj katalog Models do katalogu głównego projektu.

  2. Dodaj klasę Book do katalogu Models przy użyciu następującego kodu:

    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!;
    }
    

    W poprzedniej klasie właściwość Id jest:

    • Wymagane do mapowania obiektu Common Language Runtime (CLR) na kolekcję MongoDB.
    • Dodaj adnotację , [BsonId] aby ustawić tę właściwość jako klucz podstawowy dokumentu.
    • Adnotacje z parametrem [BsonRepresentation(BsonType.ObjectId)] umożliwiają przekazywanie parametru jako typu string zamiast struktury ObjectId . Mongo obsługuje konwersję z string na ObjectId.

    Właściwość BookName jest oznaczona adnotacją z atrybutem [BsonElement] . Wartość atrybutu Name reprezentuje nazwę właściwości w kolekcji MongoDB.

Dodawanie modelu konfiguracji

  1. Dodaj następujące wartości konfiguracji bazy danych do :appsettings.json

    {
      "BookStoreDatabase": {
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookStore",
        "BooksCollectionName": "Books"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    
  2. Dodaj klasę BookStoreDatabaseSettings do katalogu Models przy użyciu następującego kodu:

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

    Poprzednia BookStoreDatabaseSettings klasa służy do przechowywania appsettings.json wartości właściwości pliku BookStoreDatabase . Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie instancja konfiguracji, do której wiąże się sekcja pliku appsettings.json, jest zarejestrowana w kontenerze Dependency Injection (DI). Na przykład właściwość obiektu BookStoreDatabaseSettings jest wypełniana właściwością ConnectionString w BookStoreDatabase:ConnectionString.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BookStoreDatabaseSettings.

    using BookStoreApi.Models;
    

Dodaj usługę operacji CRUD

  1. Dodaj katalog Services do katalogu głównego projektu.

  2. Dodaj klasę BooksService do katalogu Services za pomocą następującego kodu:

    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);
    }
    

    W poprzednim kodzie instancja BookStoreDatabaseSettings jest pobierana z DI za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie klasa BooksService jest zarejestrowana w DI w celu obsługi wstrzykiwania konstruktora w klasach korzystających. Jednostkowy okres istnienia usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClient. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB, MongoClient należy zarejestrować w DI z czasem życia singletona.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BooksService.

    using BookStoreApi.Services;
    

Klasa BooksService używa następujących MongoDB.Driver elementów członkowskich do uruchamiania operacji CRUD względem bazy danych:

  • MongoClient: pobiera instancję serwera do wykonywania operacji na bazie danych. Konstruktor tej klasy jest udostępniany w parametry połączenia bazy danych MongoDB:

    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: reprezentuje bazę danych Mongo do uruchamiania operacji. W tym samouczku użyto ogólnej metody GetCollection<TDocument>(collection) w interfejsie, aby uzyskać dostęp do danych w określonej kolekcji. Uruchom operacje CRUD względem kolekcji po wywołaniu tej metody. W wywołaniu GetCollection<TDocument>(collection) metody:

    • collection reprezentuje nazwę kolekcji.
    • TDocument reprezentuje typ obiektu CLR przechowywany w kolekcji.

GetCollection<TDocument>(collection) Zwraca obiekt MongoCollection reprezentujący kolekcję. W tym samouczku następujące metody są wywoływane w kolekcji:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<TDocument>: Zwraca wszystkie dokumenty w kolekcji, które pasują do podanych kryteriów wyszukiwania.
  • InsertOneAsync: wstawia podany obiekt jako nowy dokument w kolekcji.
  • ReplaceOneAsync: zastępuje pojedynczy dokument pasujący do podanych kryteriów wyszukiwania podanym obiektem.

Dodawanie kontrolera

Dodaj klasę BooksController do katalogu Controllers z następującym kodem:

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();
    }
}

Poprzedni kontroler internetowego interfejsu API:

  • Używa klasy do uruchamiania operacji CRUD BooksService.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction w metodzie akcji Create, aby zwrócić odpowiedź HTTP 201. Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction również dodaje nagłówek Location do odpowiedzi. Nagłówek Location wskazuje URI nowo utworzonej książki.

Przetestuj internetowy interfejs API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/books, gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontrolera Get. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

    [
      {
        "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. Przejdź do https://localhost:<port>/api/books/{id here}, aby przetestować przeciążoną metodę akcji kontrolera. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

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

Konfigurowanie opcji serializacji JSON

Istnieją dwa szczegóły dotyczące odpowiedzi JSON zwróconych w sekcji Testowanie internetowego interfejsu API :

  • Domyślne formatowanie nazw właściwości w stylu camel case powinno zostać zmienione, aby odpowiadało stylowi Pascal w nazwach właściwości obiektu CLR.
  • Właściwość bookName powinna zostać zwrócona jako Name.

Aby spełnić powyższe wymagania, wprowadź następujące zmiany:

  1. W Program.cs, dołącz następujący wyróżniony kod do wywołania metody AddControllers.

    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);
    

    Po powyższej zmianie nazwy właściwości w serializowanej odpowiedzi JSON interfejsu API sieci Web są zgodne z odpowiednimi nazwami właściwości w typie obiektu CLR. Na przykład właściwość Book klasy Author serializuje się jako Author zamiast author.

  2. W Models/Book.cspliku dodaj adnotację do BookName właściwości za pomocą atrybutu [JsonPropertyName] :

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

    Wartość [JsonPropertyName] atrybutu Name reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.

  3. Dodaj następujący kod na początku Models/Book.cs , aby rozwiązać odwołanie do atrybutu [JsonProperty]:

    using System.Text.Json.Serialization;
    
  4. Powtórz kroki zdefiniowane w sekcji Testowanie internetowego interfejsu API . Zwróć uwagę na różnicę w nazwach właściwości JSON.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć webowe interfejsy API i SPA, użyj jednego z następujących rozwiązań:

Duende Identity Server to struktura OpenID Connect i OAuth 2.0 dla ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Dodatkowe zasoby

W tym samouczku tworzony jest webowy interfejs API, który wykonuje operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL MongoDB.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Konfigurowanie bazy danych MongoDB
  • Tworzenie bazy danych MongoDB
  • Definiowanie kolekcji i schematu bazy danych MongoDB
  • Wykonywanie operacji CRUD bazy danych MongoDB z internetowego interfejsu API
  • Dostosowywanie serializacji JSON

Wymagania wstępne

Konfigurowanie bazy danych MongoDB

Włącz dostęp do MongoDB i powłoki Mongo DB z dowolnego miejsca na maszynie deweloperskiej.

  1. W systemie Windows baza danych MongoDB jest instalowana domyślnie w katalogu C:\Program Files\MongoDB . Dodaj C:\Program Files\MongoDB\Server\<version_number>\bin do zmiennej środowiskowej PATH .

  2. Pobierz MongoDB Shell i wybierz katalog, do którego ma być wyodrębniony. Dodaj wynikową ścieżkę dla mongosh.exe do zmiennej środowiskowej PATH.

  3. Wybierz katalog na maszynie dewelopera do przechowywania danych. Na przykład C:\BooksData w systemie Windows. Utwórz katalog, jeśli nie istnieje. Powłoka mongo shell nie tworzy nowych katalogów.

  4. W powłoce poleceń systemu operacyjnego (a nie w powłoce bazy danych MongoDB) użyj następującego polecenia, aby nawiązać połączenie z bazą danych MongoDB na domyślnym porcie 27017. Zastąp <data_directory_path> element katalogiem wybranym w poprzednim kroku.

    mongod --dbpath <data_directory_path>
    

Użyj wcześniej zainstalowanej powłoki MongoDB w poniższych krokach, aby utworzyć bazę danych, stworzyć kolekcje i zarchiwizować dokumenty. Aby uzyskać więcej informacji na temat poleceń powłoki bazy danych MongoDB, zobacz mongosh.

  1. Otwórz wystąpienie powłoki poleceń bazy danych MongoDB, uruchamiając mongosh.exe lub poprzez wpisanie następującego polecenia w powłoce poleceń:

    mongosh
    
  2. W powłoce poleceń połącz się z domyślną bazą danych testowych, uruchamiając polecenie:

    use BookStore
    

    Baza danych o nazwie BookStore jest tworzona, jeśli jeszcze nie istnieje. Jeśli baza danych istnieje, jego połączenie jest otwarte dla transakcji.

  3. Books Utwórz kolekcję przy użyciu następującego polecenia:

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  4. Zdefiniuj schemat kolekcji Books i wstaw dwa dokumenty przy użyciu następującego polecenia:

    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" }])
    

    Zostanie wyświetlony wynik podobny do następującego:

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

    Uwaga

    Wartości ObjectIdpokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.

  5. Wyświetl dokumenty w bazie danych przy użyciu następującego polecenia:

    db.Books.find().pretty()
    

    Zostanie wyświetlony wynik podobny do następującego:

    {
         "_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"
     }
    

    Schemat dodaje automatycznie wygenerowaną _id właściwość typu ObjectId dla każdego dokumentu.

Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

  1. Przejdź do Plik>Nowy>Projekt.

  2. Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.

  3. Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.

  4. Wybierz strukturę .NET 7.0 (standardowe wsparcie) i wybierz pozycję Utwórz.

  5. W menu Narzędzia wybierz NuGet Menedżer pakietów>Konsola Menedżera pakietów.

  6. W oknie Konsoli Menedżera pakietów przejdź do katalogu głównego projektu. Uruchom następujące polecenie, aby zainstalować sterownik platformy .NET dla bazy danych MongoDB:

    Install-Package MongoDB.Driver
    

Dodawanie modelu jednostki

  1. Dodaj katalog Models do katalogu głównego projektu.

  2. Dodaj klasę Book do katalogu Models przy użyciu następującego kodu:

    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!;
    }
    

    W poprzedniej klasie właściwość Id jest:

    • Wymagane do mapowania obiektu Common Language Runtime (CLR) na kolekcję MongoDB.
    • Dodaj adnotację , [BsonId] aby ustawić tę właściwość jako klucz podstawowy dokumentu.
    • Adnotacje z parametrem [BsonRepresentation(BsonType.ObjectId)] umożliwiają przekazywanie parametru jako typu string zamiast struktury ObjectId . Mongo obsługuje konwersję z string na ObjectId.

    Właściwość BookName jest oznaczona adnotacją z atrybutem [BsonElement] . Wartość atrybutu Name reprezentuje nazwę właściwości w kolekcji MongoDB.

Dodawanie modelu konfiguracji

  1. Dodaj następujące wartości konfiguracji bazy danych do :appsettings.json

    {
      "BookStoreDatabase": {
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookStore",
        "BooksCollectionName": "Books"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    
  2. Dodaj klasę BookStoreDatabaseSettings do katalogu Models przy użyciu następującego kodu:

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

    Poprzednia BookStoreDatabaseSettings klasa służy do przechowywania appsettings.json wartości właściwości pliku BookStoreDatabase . Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie instancja konfiguracji, do której wiąże się sekcja pliku appsettings.json, jest zarejestrowana w kontenerze Dependency Injection (DI). Na przykład właściwość obiektu BookStoreDatabaseSettings jest wypełniana właściwością ConnectionString w BookStoreDatabase:ConnectionString.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BookStoreDatabaseSettings.

    using BookStoreApi.Models;
    

Dodaj usługę operacji CRUD

  1. Dodaj katalog Services do katalogu głównego projektu.

  2. Dodaj klasę BooksService do katalogu Services za pomocą następującego kodu:

    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);
    }
    

    W poprzednim kodzie instancja BookStoreDatabaseSettings jest pobierana z DI za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie klasa BooksService jest zarejestrowana w DI w celu obsługi wstrzykiwania konstruktora w klasach korzystających. Jednostkowy okres istnienia usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClient. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB, MongoClient należy zarejestrować w DI z czasem życia singletona.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BooksService.

    using BookStoreApi.Services;
    

Klasa BooksService używa następujących MongoDB.Driver elementów członkowskich do uruchamiania operacji CRUD względem bazy danych:

  • MongoClient: pobiera instancję serwera do wykonywania operacji na bazie danych. Konstruktor tej klasy otrzymuje ciąg połączenia MongoDB.

    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: reprezentuje bazę danych Mongo do uruchamiania operacji. W tym samouczku użyto ogólnej metody GetCollection<TDocument>(collection) w interfejsie, aby uzyskać dostęp do danych w określonej kolekcji. Uruchom operacje CRUD względem kolekcji po wywołaniu tej metody. W wywołaniu GetCollection<TDocument>(collection) metody:

    • collection reprezentuje nazwę kolekcji.
    • TDocument reprezentuje typ obiektu CLR przechowywany w kolekcji.

GetCollection<TDocument>(collection) Zwraca obiekt MongoCollection reprezentujący kolekcję. W tym samouczku następujące metody są wywoływane w kolekcji:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<TDocument>: Zwraca wszystkie dokumenty w kolekcji, które pasują do podanych kryteriów wyszukiwania.
  • InsertOneAsync: wstawia podany obiekt jako nowy dokument w kolekcji.
  • ReplaceOneAsync: zastępuje pojedynczy dokument pasujący do podanych kryteriów wyszukiwania podanym obiektem.

Dodawanie kontrolera

Dodaj klasę BooksController do katalogu Controllers z następującym kodem:

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();
    }
}

Poprzedni kontroler internetowego interfejsu API:

  • Używa klasy do uruchamiania operacji CRUD BooksService.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction w metodzie akcji Create, aby zwrócić odpowiedź HTTP 201. Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction również dodaje nagłówek Location do odpowiedzi. Nagłówek Location wskazuje URI nowo utworzonej książki.

Przetestuj internetowy interfejs API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/books, gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontrolera Get. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

    [
      {
        "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. Przejdź do https://localhost:<port>/api/books/{id here}, aby przetestować przeciążoną metodę akcji kontrolera. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

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

Konfigurowanie opcji serializacji JSON

Istnieją dwa szczegóły dotyczące odpowiedzi JSON zwróconych w sekcji Testowanie internetowego interfejsu API :

  • Domyślne formatowanie nazw właściwości w stylu camel case powinno zostać zmienione, aby odpowiadało stylowi Pascal w nazwach właściwości obiektu CLR.
  • Właściwość bookName powinna zostać zwrócona jako Name.

Aby spełnić powyższe wymagania, wprowadź następujące zmiany:

  1. W Program.cs, dołącz następujący wyróżniony kod do wywołania metody AddControllers.

    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);
    

    Po powyższej zmianie nazwy właściwości w serializowanej odpowiedzi JSON interfejsu API sieci Web są zgodne z odpowiednimi nazwami właściwości w typie obiektu CLR. Na przykład właściwość Book klasy Author serializuje się jako Author zamiast author.

  2. W Models/Book.cspliku dodaj adnotację do BookName właściwości za pomocą atrybutu [JsonPropertyName] :

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

    Wartość [JsonPropertyName] atrybutu Name reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.

  3. Dodaj następujący kod na początku Models/Book.cs , aby rozwiązać odwołanie do atrybutu [JsonProperty]:

    using System.Text.Json.Serialization;
    
  4. Powtórz kroki zdefiniowane w sekcji Testowanie internetowego interfejsu API . Zwróć uwagę na różnicę w nazwach właściwości JSON.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć webowe interfejsy API i SPA, użyj jednego z następujących rozwiązań:

Duende Identity Server to struktura OpenID Connect i OAuth 2.0 dla ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Dodatkowe zasoby

W tym samouczku tworzony jest webowy interfejs API, który wykonuje operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL MongoDB.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Konfigurowanie bazy danych MongoDB
  • Tworzenie bazy danych MongoDB
  • Definiowanie kolekcji i schematu bazy danych MongoDB
  • Wykonywanie operacji CRUD bazy danych MongoDB z internetowego interfejsu API
  • Dostosowywanie serializacji JSON

Wymagania wstępne

Konfigurowanie bazy danych MongoDB

Włącz dostęp do MongoDB i powłoki Mongo DB z dowolnego miejsca na maszynie deweloperskiej.

  1. W systemie Windows baza danych MongoDB jest instalowana domyślnie w katalogu C:\Program Files\MongoDB . Dodaj C:\Program Files\MongoDB\Server\<version_number>\bin do zmiennej środowiskowej PATH .

  2. Pobierz MongoDB Shell i wybierz katalog, do którego ma być wyodrębniony. Dodaj wynikową ścieżkę dla mongosh.exe do zmiennej środowiskowej PATH.

  3. Wybierz katalog na maszynie dewelopera do przechowywania danych. Na przykład C:\BooksData w systemie Windows. Utwórz katalog, jeśli nie istnieje. Powłoka mongo shell nie tworzy nowych katalogów.

  4. W powłoce poleceń systemu operacyjnego (a nie w powłoce bazy danych MongoDB) użyj następującego polecenia, aby nawiązać połączenie z bazą danych MongoDB na domyślnym porcie 27017. Zastąp <data_directory_path> element katalogiem wybranym w poprzednim kroku.

    mongod --dbpath <data_directory_path>
    

Użyj wcześniej zainstalowanej powłoki MongoDB w poniższych krokach, aby utworzyć bazę danych, stworzyć kolekcje i zarchiwizować dokumenty. Aby uzyskać więcej informacji na temat poleceń powłoki bazy danych MongoDB, zobacz mongosh.

  1. Otwórz wystąpienie powłoki poleceń bazy danych MongoDB, uruchamiając mongosh.exe lub poprzez wpisanie następującego polecenia w powłoce poleceń:

    mongosh
    
  2. W powłoce poleceń połącz się z domyślną bazą danych testowych, uruchamiając polecenie:

    use BookStore
    

    Baza danych o nazwie BookStore jest tworzona, jeśli jeszcze nie istnieje. Jeśli baza danych istnieje, jego połączenie jest otwarte dla transakcji.

  3. Books Utwórz kolekcję przy użyciu następującego polecenia:

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  4. Zdefiniuj schemat kolekcji Books i wstaw dwa dokumenty przy użyciu następującego polecenia:

    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" }])
    

    Zostanie wyświetlony wynik podobny do następującego:

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

    Uwaga

    Wartości ObjectIdpokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.

  5. Wyświetl dokumenty w bazie danych przy użyciu następującego polecenia:

    db.Books.find().pretty()
    

    Zostanie wyświetlony wynik podobny do następującego:

    {
         "_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"
     }
    

    Schemat dodaje automatycznie wygenerowaną _id właściwość typu ObjectId dla każdego dokumentu.

Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

  1. Przejdź do Plik>Nowy>Projekt.

  2. Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.

  3. Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.

  4. Wybierz strukturę .NET 6.0 (obsługa długoterminowa) i wybierz pozycję Utwórz.

  5. W oknie Konsoli Menedżera pakietów przejdź do katalogu głównego projektu. Uruchom następujące polecenie, aby zainstalować sterownik platformy .NET dla bazy danych MongoDB:

    Install-Package MongoDB.Driver
    

Dodawanie modelu jednostki

  1. Dodaj katalog Models do katalogu głównego projektu.

  2. Dodaj klasę Book do katalogu Models przy użyciu następującego kodu:

    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!;
    }
    

    W poprzedniej klasie właściwość Id jest:

    • Wymagane do mapowania obiektu Common Language Runtime (CLR) na kolekcję MongoDB.
    • Dodaj adnotację , [BsonId] aby ustawić tę właściwość jako klucz podstawowy dokumentu.
    • Adnotacje z parametrem [BsonRepresentation(BsonType.ObjectId)] umożliwiają przekazywanie parametru jako typu string zamiast struktury ObjectId . Mongo obsługuje konwersję z string na ObjectId.

    Właściwość BookName jest oznaczona adnotacją z atrybutem [BsonElement] . Wartość atrybutu Name reprezentuje nazwę właściwości w kolekcji MongoDB.

Dodawanie modelu konfiguracji

  1. Dodaj następujące wartości konfiguracji bazy danych do :appsettings.json

    {
        "BookStoreDatabase": {
            "ConnectionString": "mongodb://localhost:27017",
            "DatabaseName": "BookStore",
            "BooksCollectionName": "Books"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning"
            }
        },
        "AllowedHosts": "*"
    }
    
  2. Dodaj klasę BookStoreDatabaseSettings do katalogu Models przy użyciu następującego kodu:

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

    Poprzednia BookStoreDatabaseSettings klasa służy do przechowywania appsettings.json wartości właściwości pliku BookStoreDatabase . Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie instancja konfiguracji, do której wiąże się sekcja pliku appsettings.json, jest zarejestrowana w kontenerze Dependency Injection (DI). Na przykład właściwość obiektu BookStoreDatabaseSettings jest wypełniana właściwością ConnectionString w BookStoreDatabase:ConnectionString.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BookStoreDatabaseSettings.

    using BookStoreApi.Models;
    

Dodaj usługę operacji CRUD

  1. Dodaj katalog Services do katalogu głównego projektu.

  2. Dodaj klasę BooksService do katalogu Services za pomocą następującego kodu:

    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);
    }
    

    W poprzednim kodzie instancja BookStoreDatabaseSettings jest pobierana z DI za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.

  3. Dodaj następujący wyróżniony kod do Program.cs:

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

    W poprzednim kodzie klasa BooksService jest zarejestrowana w DI w celu obsługi wstrzykiwania konstruktora w klasach korzystających. Jednostkowy okres istnienia usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClient. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB, MongoClient należy zarejestrować w DI z czasem życia singletona.

  4. Dodaj następujący kod na górze Program.cs, aby rozwiązać odwołanie BooksService.

    using BookStoreApi.Services;
    

Klasa BooksService używa następujących MongoDB.Driver elementów członkowskich do uruchamiania operacji CRUD względem bazy danych:

  • MongoClient: pobiera instancję serwera do wykonywania operacji na bazie danych. Konstruktor tej klasy otrzymuje ciąg połączenia MongoDB.

    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: reprezentuje bazę danych Mongo do uruchamiania operacji. W tym samouczku użyto ogólnej metody GetCollection<TDocument>(collection) w interfejsie, aby uzyskać dostęp do danych w określonej kolekcji. Uruchom operacje CRUD względem kolekcji po wywołaniu tej metody. W wywołaniu GetCollection<TDocument>(collection) metody:

    • collection reprezentuje nazwę kolekcji.
    • TDocument reprezentuje typ obiektu CLR przechowywany w kolekcji.

GetCollection<TDocument>(collection) Zwraca obiekt MongoCollection reprezentujący kolekcję. W tym samouczku następujące metody są wywoływane w kolekcji:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<TDocument>: Zwraca wszystkie dokumenty w kolekcji, które pasują do podanych kryteriów wyszukiwania.
  • InsertOneAsync: wstawia podany obiekt jako nowy dokument w kolekcji.
  • ReplaceOneAsync: zastępuje pojedynczy dokument pasujący do podanych kryteriów wyszukiwania podanym obiektem.

Dodawanie kontrolera

Dodaj klasę BooksController do katalogu Controllers z następującym kodem:

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();
    }
}

Poprzedni kontroler internetowego interfejsu API:

  • Używa klasy do uruchamiania operacji CRUD BooksService.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction w metodzie akcji Create, aby zwrócić odpowiedź HTTP 201. Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction również dodaje nagłówek Location do odpowiedzi. Nagłówek Location wskazuje URI nowo utworzonej książki.

Przetestuj internetowy interfejs API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/books, gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontrolera Get. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

    [
      {
        "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. Przejdź do https://localhost:<port>/api/books/{id here}, aby przetestować przeciążoną metodę akcji kontrolera. Zostanie wyświetlona odpowiedź JSON podobna do następującej:

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

Konfigurowanie opcji serializacji JSON

Istnieją dwa szczegóły dotyczące odpowiedzi JSON zwróconych w sekcji Testowanie internetowego interfejsu API :

  • Domyślne formatowanie nazw właściwości w stylu camel case powinno zostać zmienione, aby odpowiadało stylowi Pascal w nazwach właściwości obiektu CLR.
  • Właściwość bookName powinna zostać zwrócona jako Name.

Aby spełnić powyższe wymagania, wprowadź następujące zmiany:

  1. W Program.cs, dołącz następujący wyróżniony kod do wywołania metody AddControllers.

    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);
    

    Po powyższej zmianie nazwy właściwości w serializowanej odpowiedzi JSON interfejsu API sieci Web są zgodne z odpowiednimi nazwami właściwości w typie obiektu CLR. Na przykład właściwość Book klasy Author serializuje się jako Author zamiast author.

  2. W Models/Book.cspliku dodaj adnotację do BookName właściwości za pomocą atrybutu [JsonPropertyName] :

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

    Wartość [JsonPropertyName] atrybutu Name reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.

  3. Dodaj następujący kod na początku Models/Book.cs , aby rozwiązać odwołanie do atrybutu [JsonProperty]:

    using System.Text.Json.Serialization;
    
  4. Powtórz kroki zdefiniowane w sekcji Testowanie internetowego interfejsu API . Zwróć uwagę na różnicę w nazwach właściwości JSON.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć webowe interfejsy API i SPA, użyj jednego z następujących rozwiązań:

Duende Identity Server to struktura OpenID Connect i OAuth 2.0 dla ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Ważne

Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Dodatkowe zasoby

W tym samouczku tworzony jest webowy interfejs API, który wykonuje operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL MongoDB.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Konfigurowanie bazy danych MongoDB
  • Tworzenie bazy danych MongoDB
  • Definiowanie kolekcji i schematu bazy danych MongoDB
  • Wykonywanie operacji CRUD bazy danych MongoDB z internetowego interfejsu API
  • Dostosowywanie serializacji JSON

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Konfigurowanie bazy danych MongoDB

W przypadku korzystania z systemu Windows baza danych MongoDB jest instalowana domyślnie w folderze C:\Program Files\MongoDB . Dodaj C:\Program Files\MongoDB\Server\<version_number>\bin do zmiennej środowiskowej Path . Ta zmiana umożliwia dostęp do bazy danych MongoDB z dowolnego miejsca na maszynie dewelopera.

Użyj mongo shell w poniższych krokach, aby utworzyć bazę danych, utworzyć kolekcje i przechowywać dokumenty. Aby uzyskać więcej informacji na temat poleceń w powłoce mongo, zobacz Jak korzystać z powłoki mongo.

  1. Wybierz katalog na komputerze deweloperskim do przechowywania danych. Na przykład C:\BooksData w systemie Windows. Utwórz katalog, jeśli nie istnieje. Powłoka mongo shell nie tworzy nowych katalogów.

  2. Otwórz wiersz poleceń. Uruchom następujące polecenie, aby nawiązać połączenie z bazą danych MongoDB na domyślnym porcie 27017. Pamiętaj, aby zastąpić <data_directory_path> katalogiem wybranym w poprzednim kroku.

    mongod --dbpath <data_directory_path>
    
  3. Otwórz inne okno powłoki poleceń. Połącz się z domyślną testową bazą danych, uruchamiając następujące polecenie:

    mongo
    
  4. Uruchom następujące polecenie w konsoli poleceń:

    use BookstoreDb
    

    Baza danych o nazwie BookstoreDb jest tworzona, jeśli jeszcze nie istnieje. Jeśli baza danych istnieje, jego połączenie jest otwarte dla transakcji.

  5. Books Utwórz kolekcję przy użyciu następującego polecenia:

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  6. Zdefiniuj schemat kolekcji Books i wstaw dwa dokumenty przy użyciu następującego polecenia:

    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'}])
    

    Zostanie wyświetlony następujący wynik:

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

    Uwaga

    Identyfikatory pokazane w tym artykule nie będą zgodne z identyfikatorami po uruchomieniu tego przykładu.

  7. Wyświetl dokumenty w bazie danych przy użyciu następującego polecenia:

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

    Zostanie wyświetlony następujący wynik:

    {
      "_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"
    }
    

    Schemat dodaje automatycznie wygenerowaną _id właściwość typu ObjectId dla każdego dokumentu.

Baza danych jest gotowa. Możesz rozpocząć tworzenie internetowego interfejsu API platformy ASP.NET Core.

Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

  1. Przejdź do Plik>Nowy>Projekt.

  2. Wybierz typ projektu ASP.NET Core Web Application, a następnie wybierz pozycję Dalej.

  3. Nadaj projektowi nazwę BooksApi i wybierz pozycję Utwórz.

  4. Wybierz platformę docelową .NET Core i ASP.NET Core 3.0. Wybierz szablon projektu interfejsu API , a następnie wybierz pozycję Utwórz.

  5. Odwiedź galerię NuGet: MongoDB.Driver , aby określić najnowszą stabilną wersję sterownika platformy .NET dla bazy danych MongoDB. W oknie Konsoli Menedżera pakietów przejdź do katalogu głównego projektu. Uruchom następujące polecenie, aby zainstalować sterownik platformy .NET dla bazy danych MongoDB:

    Install-Package MongoDB.Driver -Version {VERSION}
    

Dodawanie modelu jednostki

  1. Dodaj katalog Models do katalogu głównego projektu.

  2. Dodaj klasę Book do katalogu Models przy użyciu następującego kodu:

    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; }
        }
    }
    

    W poprzedniej klasie właściwość Id jest:

    • Wymagane do mapowania obiektu Common Language Runtime (CLR) na kolekcję MongoDB.
    • Dodaj adnotację , [BsonId] aby ustawić tę właściwość jako klucz podstawowy dokumentu.
    • Adnotacje z parametrem [BsonRepresentation(BsonType.ObjectId)] umożliwiają przekazywanie parametru jako typu string zamiast struktury ObjectId . Mongo obsługuje konwersję z string na ObjectId.

    Właściwość BookName jest oznaczona adnotacją z atrybutem [BsonElement] . Wartość atrybutu Name reprezentuje nazwę właściwości w kolekcji MongoDB.

Dodawanie modelu konfiguracji

  1. Dodaj następujące wartości konfiguracji bazy danych do :appsettings.json

    {
      "BookstoreDatabaseSettings": {
        "BooksCollectionName": "Books",
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookstoreDb"
      },
      "Logging": {
        "IncludeScopes": false,
        "Debug": {
          "LogLevel": {
            "Default": "Warning"
          }
        },
        "Console": {
          "LogLevel": {
            "Default": "Warning"
          }
        }
      }
    }
    
  2. BookstoreDatabaseSettings.cs Dodaj plik do katalogu Models przy użyciu następującego kodu:

    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; }
        }
    }
    

    Poprzednia BookstoreDatabaseSettings klasa służy do przechowywania appsettings.json wartości właściwości pliku BookstoreDatabaseSettings . Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.

  3. Dodaj następujący wyróżniony kod do Startup.ConfigureServices:

    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();
    }
    

    W wcześniejszym kodzie

    • Instancja konfiguracji, z którą wiąże się sekcja pliku appsettings.json, jest zarejestrowana w kontenerze DI (Wstrzykiwanie zależności). Na przykład właściwość BookstoreDatabaseSettings obiektu ConnectionString jest wypełniana właściwością BookstoreDatabaseSettings:ConnectionString w appsettings.json.
    • Interfejs IBookstoreDatabaseSettings jest rejestrowany w di z pojedynczym okresem istnienia usługi. Po wstrzyknięciu, wystąpienie interfejsu przekształca się w obiekt BookstoreDatabaseSettings.
  4. Dodaj następujący kod na początku Startup.cs, aby rozwiązać odwołania BookstoreDatabaseSettings i IBookstoreDatabaseSettings.

    using BooksApi.Models;
    

Dodaj usługę operacji CRUD

  1. Dodaj katalog Services do katalogu głównego projektu.

  2. Dodaj klasę BookService do katalogu Services za pomocą następującego kodu:

    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);
        }
    }
    

    W poprzednim kodzie instancja IBookstoreDatabaseSettings jest pobierana z DI za pośrednictwem iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.

  3. Dodaj następujący wyróżniony kod do Startup.ConfigureServices:

    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();
    }
    

    W poprzednim kodzie klasa BookService jest zarejestrowana w DI w celu obsługi wstrzykiwania konstruktora w klasach korzystających. Jednostkowy okres istnienia usługi jest najbardziej odpowiedni, ponieważ BookService pobiera bezpośrednią zależność od MongoClient. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB, MongoClient należy zarejestrować w DI z czasem życia singletona.

  4. Dodaj następujący kod na górze Startup.cs, aby rozwiązać odwołanie BookService.

    using BooksApi.Services;
    

Klasa BookService używa następujących MongoDB.Driver elementów członkowskich do uruchamiania operacji CRUD względem bazy danych:

  • MongoClient: pobiera instancję serwera do wykonywania operacji na bazie danych. Konstruktor tej klasy otrzymuje ciąg połączenia MongoDB.

    public BookService(IBookstoreDatabaseSettings settings)
    {
        var client = new MongoClient(settings.ConnectionString);
        var database = client.GetDatabase(settings.DatabaseName);
    
        _books = database.GetCollection<Book>(settings.BooksCollectionName);
    }
    
  • IMongoDatabase: reprezentuje bazę danych Mongo do uruchamiania operacji. W tym samouczku użyto ogólnej metody GetCollection<TDocument>(collection) w interfejsie, aby uzyskać dostęp do danych w określonej kolekcji. Uruchom operacje CRUD względem kolekcji po wywołaniu tej metody. W wywołaniu GetCollection<TDocument>(collection) metody:

    • collection reprezentuje nazwę kolekcji.
    • TDocument reprezentuje typ obiektu CLR przechowywany w kolekcji.

GetCollection<TDocument>(collection) Zwraca obiekt MongoCollection reprezentujący kolekcję. W tym samouczku następujące metody są wywoływane w kolekcji:

  • DeleteOne: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<TDocument>: Zwraca wszystkie dokumenty w kolekcji, które pasują do podanych kryteriów wyszukiwania.
  • InsertOne: wstawia podany obiekt jako nowy dokument w kolekcji.
  • ReplaceOne: zastępuje pojedynczy dokument pasujący do podanych kryteriów wyszukiwania podanym obiektem.

Dodawanie kontrolera

Dodaj klasę BooksController do katalogu Controllers z następującym kodem:

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();
        }
    }
}

Poprzedni kontroler internetowego interfejsu API:

  • Używa klasy do uruchamiania operacji CRUD BookService.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtRoute w metodzie akcji Create, aby zwrócić odpowiedź HTTP 201. Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtRoute również dodaje nagłówek Location do odpowiedzi. Nagłówek Location wskazuje URI nowo utworzonej książki.

Przetestuj internetowy interfejs API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do strony , https://localhost:<port>/api/books aby przetestować bezparametrową Get metodę akcji kontrolera. Zostanie wyświetlona następująca odpowiedź JSON:

    [
      {
        "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. Przejdź do https://localhost:<port>/api/books/{id here}, aby przetestować przeciążoną metodę akcji kontrolera. Zostanie wyświetlona następująca odpowiedź JSON:

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

Konfigurowanie opcji serializacji JSON

Istnieją dwa szczegóły dotyczące odpowiedzi JSON zwróconych w sekcji Testowanie internetowego interfejsu API :

  • Domyślne formatowanie nazw właściwości w stylu camel case powinno zostać zmienione, aby odpowiadało stylowi Pascal w nazwach właściwości obiektu CLR.
  • Właściwość bookName powinna zostać zwrócona jako Name.

Aby spełnić powyższe wymagania, wprowadź następujące zmiany:

  1. Json.NET został usunięty z platformy udostępnionej ASP.NET. Dodaj odwołanie do pakietu Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  2. W Startup.ConfigureServices, dołącz następujący wyróżniony kod do wywołania metody AddControllers.

    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());
    }
    

    Po powyższej zmianie nazwy właściwości w serializowanej odpowiedzi JSON interfejsu API sieci Web są zgodne z odpowiednimi nazwami właściwości w typie obiektu CLR. Na przykład właściwość klasy BookAuthor serializuje się jako Author.

  3. W Models/Book.cs, adnotuj właściwość BookName za pomocą następującego atrybutu [JsonProperty].

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

    Wartość [JsonProperty] atrybutu Name reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.

  4. Dodaj następujący kod na początku Models/Book.cs , aby rozwiązać odwołanie do atrybutu [JsonProperty]:

    using Newtonsoft.Json;
    
  5. Powtórz kroki zdefiniowane w sekcji Testowanie internetowego interfejsu API . Zwróć uwagę na różnicę w nazwach właściwości JSON.

Dodawanie obsługi uwierzytelniania do internetowego interfejsu API

ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć webowe interfejsy API i SPA, użyj jednego z następujących rozwiązań:

Duende IdentityServer to platforma OpenID Connect i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende IdentityServer umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Aby uzyskać więcej informacji, zobacz Omówienie Duende IdentityServer.

Aby uzyskać więcej informacji na temat innych dostawców uwierzytelniania, zobacz Community OSS authentication options for ASP.NET Core (Opcje uwierzytelniania systemu operacyjnego Community dla platformy ASP.NET Core)

Następne kroki

Aby uzyskać więcej informacji na temat tworzenia ASP.NET Core internetowych interfejsów API, zobacz następujące zasoby: