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ę tego artykułu platformy .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ę tego artykułu platformy .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ę tego artykułu platformy .NET 9.

Przez Pratik Khandelwal i Scott Addie

W tym samouczku tworzony jest internetowy interfejs API, który uruchamia operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL bazy danych 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 bazy danych MongoDB i powłoki MongoDB z dowolnego miejsca na maszynie programistycznej (Windows/Linux/macOS):

  1. Pobierz i zainstaluj powłokę mongoDB:

    • macOS/Linux: wybierz katalog do wyodrębnienia powłoki Bazy danych MongoDB. Dodaj wynikową ścieżkę do mongosh zmiennej środowiskowej PATH .
    • Windows: powłoka MongoDB (mongosh.exe) jest zainstalowana w folderze C:\Users<user>\AppData\Local\Programs\mongosh. Dodaj wynikową ścieżkę do mongosh.exe 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ę do mongodb 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, tworzyć kolekcje i przechowywać 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 polecenie mongosh.exe.

  2. W powłoce poleceń połącz się z domyślną testowej bazy danych, uruchamiając następujące polecenie:

    mongosh
    
  3. Uruchom następujące polecenie w powłoce poleceń:

    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.

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

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  5. 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ń.

  6. 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 pozycji 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 Menedżer pakietów Console (Konsola Menedżer 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 Id właściwość to:

    • Wymagane do mapowania obiektu Środowiska uruchomieniowego języka wspólnego (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 wystąpienie konfiguracji, z którym appsettings.json wiąże się sekcja pliku BookStoreDatabase , jest zarejestrowane w kontenerze wstrzykiwania zależności (DI). Na przykład BookStoreDatabaseSettings właściwość obiektu ConnectionString jest wypełniana właściwością BookStoreDatabase:ConnectionString w pliku appsettings.json.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BookStoreDatabaseSettings ten problem:

    using BookStoreApi.Models;
    

Dodawanie usługi 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 BookStoreDatabaseSettings wystąpienie jest pobierane z di za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodawanie modelu 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 jest zarejestrowana BooksService w di w celu obsługi wstrzykiwania konstruktora w klasach zużywających. Okres istnienia pojedynczej usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClientelementu . Zgodnie z oficjalnymi wytycznymiMongoClient dotyczącymi ponownego używania klienta Mongo należy zarejestrować w di z pojedynczym okresem istnienia usługi.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BooksService ten problem:

    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: odczytuje wystąpienie serwera na potrzeby uruchamiania operacji bazy 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 w kolekcji są wywoływane następujące metody:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<dokument:> zwraca wszystkie dokumenty w kolekcji zgodne z podanymi kryteriami 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 BooksService operacji CRUD.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction metodę Create akcji, aby zwrócić odpowiedź HTTP 201 . Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction Dodaje Location również nagłówek do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonej książki.

Testowanie internetowego interfejsu API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/bookslokalizacji , gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować metodę akcji bez parametrów Get kontrolera, wybierz pozycję Wypróbuj>wykonanie. 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 strony , https://localhost:<port>/api/books/{id here} aby przetestować przeciążonej Get metody 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ślna wielkość liter wielbłądów nazw właściwości powinna zostać zmieniona tak, aby odpowiadała wielkości liter Pascal nazw 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.cspliku połącz następujący wyróżniony kod z wywołaniem AddControllers metody:

    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 Book właściwość 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 w górnej części elementu , aby rozpoznać odwołanie do atrybutu Models/Book.cs [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ć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

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

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego 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 Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

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

Dodatkowe zasoby

W tym samouczku tworzony jest internetowy interfejs API, który uruchamia operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL bazy danych 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 powłoki MongoDB i Mongo DB z dowolnego miejsca na maszynie dewelopera:

  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 powłokę bazy danych MongoDB i wybierz katalog, do których ma być wyodrębnione. Dodaj wynikową ścieżkę do mongosh.exe 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 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, tworzyć kolekcje i przechowywać 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 polecenie mongosh.exe.

  2. W powłoce poleceń połącz się z domyślną testowej bazy danych, uruchamiając następujące polecenie:

    mongosh
    
  3. Uruchom następujące polecenie w powłoce poleceń:

    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.

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

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  5. 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ń.

  6. 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 pozycji 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 (obsługa terminów standardowych) i wybierz pozycję Utwórz.

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

  6. W oknie Menedżer pakietów Console (Konsola Menedżer 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 Id właściwość to:

    • Wymagane do mapowania obiektu Środowiska uruchomieniowego języka wspólnego (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 wystąpienie konfiguracji, z którym appsettings.json wiąże się sekcja pliku BookStoreDatabase , jest zarejestrowane w kontenerze wstrzykiwania zależności (DI). Na przykład BookStoreDatabaseSettings właściwość obiektu ConnectionString jest wypełniana właściwością BookStoreDatabase:ConnectionString w pliku appsettings.json.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BookStoreDatabaseSettings ten problem:

    using BookStoreApi.Models;
    

Dodawanie usługi 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 BookStoreDatabaseSettings wystąpienie jest pobierane z di za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodawanie modelu 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 jest zarejestrowana BooksService w di w celu obsługi wstrzykiwania konstruktora w klasach zużywających. Okres istnienia pojedynczej usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClientelementu . Zgodnie z oficjalnymi wytycznymiMongoClient dotyczącymi ponownego używania klienta Mongo należy zarejestrować w di z pojedynczym okresem istnienia usługi.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BooksService ten problem:

    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: odczytuje wystąpienie serwera na potrzeby uruchamiania operacji bazy danych. Konstruktor tej klasy jest dostarczany parametry 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 w kolekcji są wywoływane następujące metody:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<dokument:> zwraca wszystkie dokumenty w kolekcji zgodne z podanymi kryteriami 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 BooksService operacji CRUD.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction metodę Create akcji, aby zwrócić odpowiedź HTTP 201 . Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction Dodaje Location również nagłówek do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonej książki.

Testowanie internetowego interfejsu API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/bookslokalizacji , gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować metodę akcji bez parametrów Get kontrolera. 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 strony , https://localhost:<port>/api/books/{id here} aby przetestować przeciążonej Get metody 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ślna wielkość liter wielbłądów nazw właściwości powinna zostać zmieniona tak, aby odpowiadała wielkości liter Pascal nazw 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.cspliku połącz następujący wyróżniony kod z wywołaniem AddControllers metody:

    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 Book właściwość 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 w górnej części elementu , aby rozpoznać odwołanie do atrybutu Models/Book.cs [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ć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

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

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego 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 Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

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

Dodatkowe zasoby

W tym samouczku tworzony jest internetowy interfejs API, który uruchamia operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL bazy danych 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 powłoki MongoDB i Mongo DB z dowolnego miejsca na maszynie dewelopera:

  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 powłokę bazy danych MongoDB i wybierz katalog, do których ma być wyodrębnione. Dodaj wynikową ścieżkę do mongosh.exe 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 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, tworzyć kolekcje i przechowywać 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 polecenie mongosh.exe.

  2. W powłoce poleceń połącz się z domyślną testowej bazy danych, uruchamiając następujące polecenie:

    mongosh
    
  3. Uruchom następujące polecenie w powłoce poleceń:

    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.

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

    db.createCollection('Books')
    

    Zostanie wyświetlony następujący wynik:

    { "ok" : 1 }
    
  5. 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ń.

  6. 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 pozycji 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 Menedżer pakietów Console (Konsola Menedżer 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 Id właściwość to:

    • Wymagane do mapowania obiektu Środowiska uruchomieniowego języka wspólnego (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 wystąpienie konfiguracji, z którym appsettings.json wiąże się sekcja pliku BookStoreDatabase , jest zarejestrowane w kontenerze wstrzykiwania zależności (DI). Na przykład BookStoreDatabaseSettings właściwość obiektu ConnectionString jest wypełniana właściwością BookStoreDatabase:ConnectionString w pliku appsettings.json.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BookStoreDatabaseSettings ten problem:

    using BookStoreApi.Models;
    

Dodawanie usługi 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 BookStoreDatabaseSettings wystąpienie jest pobierane z di za pomocą iniekcji konstruktora. Ta technika zapewnia dostęp do appsettings.json wartości konfiguracji, które zostały dodane w sekcji Dodawanie modelu 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 jest zarejestrowana BooksService w di w celu obsługi wstrzykiwania konstruktora w klasach zużywających. Okres istnienia pojedynczej usługi jest najbardziej odpowiedni, ponieważ BooksService pobiera bezpośrednią zależność od MongoClientelementu . Zgodnie z oficjalnymi wytycznymiMongoClient dotyczącymi ponownego używania klienta Mongo należy zarejestrować w di z pojedynczym okresem istnienia usługi.

  4. Dodaj następujący kod na początku, Program.cs aby rozwiązać BooksService ten problem:

    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: odczytuje wystąpienie serwera na potrzeby uruchamiania operacji bazy danych. Konstruktor tej klasy jest dostarczany parametry 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 w kolekcji są wywoływane następujące metody:

  • DeleteOneAsync: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<dokument:> zwraca wszystkie dokumenty w kolekcji zgodne z podanymi kryteriami 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 BooksService operacji CRUD.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtAction metodę Create akcji, aby zwrócić odpowiedź HTTP 201 . Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtAction Dodaje Location również nagłówek do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonej książki.

Testowanie internetowego interfejsu API

  1. Skompiluj i uruchom aplikację.

  2. Przejdź do https://localhost:<port>/api/bookslokalizacji , gdzie <port> jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować metodę akcji bez parametrów Get kontrolera. 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 strony , https://localhost:<port>/api/books/{id here} aby przetestować przeciążonej Get metody 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ślna wielkość liter wielbłądów nazw właściwości powinna zostać zmieniona tak, aby odpowiadała wielkości liter Pascal nazw 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.cspliku połącz następujący wyróżniony kod z wywołaniem AddControllers metody:

    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 Book właściwość 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 w górnej części elementu , aby rozpoznać odwołanie do atrybutu Models/Book.cs [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ć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

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

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wyłączanie logowania jednokrotnego 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 Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.

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

Dodatkowe zasoby

W tym samouczku tworzony jest internetowy interfejs API, który uruchamia operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) w bazie danych NoSQL bazy danych 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 powłoki mongo w poniższych krokach, aby utworzyć bazę danych, tworzyć kolekcje i przechowywać dokumenty. Aby uzyskać więcej informacji na temat poleceń powłoki mongo, zobacz Praca z powłoką 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 nie tworzy nowych katalogów.

  2. Otwórz powłokę 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> katalog wybrany w poprzednim kroku.

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

    mongo
    
  4. Uruchom następujące polecenie w powłoce 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

    Identyfikator pokazany w tym artykule nie będzie zgodny 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 pozycji 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ą platformy .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 Menedżer pakietów Console (Konsola Menedżer 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 Id właściwość to:

    • Wymagane do mapowania obiektu Środowiska uruchomieniowego języka wspólnego (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();
    }
    

    Powyższy kod:

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

    using BooksApi.Models;
    

Dodawanie usługi 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 IBookstoreDatabaseSettings wystąpienie jest pobierane 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 Dodawanie modelu 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 jest zarejestrowana BookService w di w celu obsługi wstrzykiwania konstruktora w klasach zużywających. Okres istnienia pojedynczej usługi jest najbardziej odpowiedni, ponieważ BookService pobiera bezpośrednią zależność od MongoClientelementu . Zgodnie z oficjalnymi wytycznymiMongoClient dotyczącymi ponownego używania klienta Mongo należy zarejestrować w di z pojedynczym okresem istnienia usługi.

  4. Dodaj następujący kod na początku, Startup.cs aby rozwiązać BookService ten problem:

    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: odczytuje wystąpienie serwera na potrzeby uruchamiania operacji bazy danych. Konstruktor tej klasy jest dostarczany parametry 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 w kolekcji są wywoływane następujące metody:

  • DeleteOne: usuwa pojedynczy dokument zgodny z podanymi kryteriami wyszukiwania.
  • Znajdź<dokument:> zwraca wszystkie dokumenty w kolekcji zgodne z podanymi kryteriami 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 BookService operacji CRUD.
  • Zawiera metody akcji do obsługi żądań HTTP GET, POST, PUT i DELETE.
  • Wywołuje CreatedAtRoute metodę Create akcji, aby zwrócić odpowiedź HTTP 201 . Kod stanu 201 to standardowa odpowiedź metody HTTP POST, która tworzy nowy zasób na serwerze. CreatedAtRoute Dodaje Location również nagłówek do odpowiedzi. Nagłówek Location określa identyfikator URI nowo utworzonej książki.

Testowanie internetowego interfejsu 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 strony , https://localhost:<port>/api/books/{id here} aby przetestować przeciążonej Get metody 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ślna wielkość liter wielbłądów nazw właściwości powinna zostać zmieniona tak, aby odpowiadała wielkości liter Pascal nazw 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 do Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  2. W Startup.ConfigureServicespliku połącz następujący wyróżniony kod z wywołaniem AddControllers metody:

    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 Book właściwość klasy Author serializuje jako Author.

  3. W Models/Book.cspliku dodaj adnotację do BookName właściwości za pomocą następującego [JsonProperty] atrybutu:

    [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 w górnej części elementu , aby rozpoznać odwołanie do atrybutu Models/Book.cs [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ć internetowe interfejsy API i spA, użyj jednego z następujących elementów:

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/wyłączanie logowania jednokrotnego 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: