Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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
Program Visual Studio 2022 z pakietem roboczym tworzenia aplikacji ASP.NET i aplikacji internetowych.
Konfigurowanie bazy danych MongoDB
Włącz dostęp do MongoDB i MongoDB Shell z dowolnego miejsca na komputerze programistycznym (Windows/Linux/macOS):
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 środowiskowejPATH
. - Windows: MongoDB Shell (mongosh.exe) jest zainstalowany w C:\Users\<user>\AppData\Local\Programs\mongosh. Dodaj wynikową ścieżkę dla
mongosh.exe
do zmiennej środowiskowejPATH
.
- macOS/Linux: Wybierz katalog, do którego chcesz wyodrębnić powłokę MongoDB. Dodaj wynikową ścieżkę dla
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 środowiskowejPATH
. - 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
.
- macOS/Linux: sprawdź katalog, w którym zainstalowano bazę danych MongoDB, zwykle w katalogu /usr/local/mongodb. Dodaj wynikową ścieżkę dla
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
.
- macOS/Linux: na przykład
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
.
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
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.
Books
Utwórz kolekcję przy użyciu następującego polecenia:db.createCollection('Books')
Zostanie wyświetlony następujący wynik:
{ "ok" : 1 }
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
ObjectId
pokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.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ść typuObjectId
dla każdego dokumentu.
Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core
- Przejdź do Plik>Nowy>Projekt.
- Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.
- Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.
- 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.
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
Dodaj katalog Models do katalogu głównego projektu.
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 typustring
zamiast struktury ObjectId . Mongo obsługuje konwersję zstring
naObjectId
.
Właściwość
BookName
jest oznaczona adnotacją z atrybutem[BsonElement]
. Wartość atrybutuName
reprezentuje nazwę właściwości w kolekcji MongoDB.
Dodawanie modelu konfiguracji
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": "*" }
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 przechowywaniaappsettings.json
wartości właściwości plikuBookStoreDatabase
. Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.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ść obiektuBookStoreDatabaseSettings
jest wypełniana właściwościąConnectionString
wBookStoreDatabase:ConnectionString
.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBookStoreDatabaseSettings
.using BookStoreApi.Models;
Dodaj usługę operacji CRUD
Dodaj katalog Services do katalogu głównego projektu.
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 doappsettings.json
wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.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ść odMongoClient
. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB,MongoClient
należy zarejestrować w DI z czasem życia singletona.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBooksService
.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łówekLocation
do odpowiedzi. NagłówekLocation
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 jakoName
.
Aby spełnić powyższe wymagania, wprowadź następujące zmiany:
W
Program.cs
, dołącz następujący wyróżniony kod do wywołania metodyAddControllers
.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
klasyAuthor
serializuje się jakoAuthor
zamiastauthor
.W
Models/Book.cs
pliku dodaj adnotację doBookName
właściwości za pomocą atrybutu[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
Wartość
[JsonPropertyName]
atrybutuName
reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.Dodaj następujący kod na początku
Models/Book.cs
, aby rozwiązać odwołanie do atrybutu[JsonProperty]
:using System.Text.Json.Serialization;
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.
Skompiluj i uruchom aplikację.
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.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ź .
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" } ]
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}} ###
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}} ###
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ź .
Treść odpowiedzi zawiera kod JSON podobny do następującego:
{ "Id": "61a6058e6c43f32854e51f52", "Name": "Clean Code", "Price": 43.15, "Category": "Computers", "Author": "Robert C. Martin" }
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 } ###
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" } ###
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.
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}} ###
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
Program Visual Studio 2022 z pakietem roboczym tworzenia aplikacji ASP.NET i aplikacji internetowych.
Konfigurowanie bazy danych MongoDB
Włącz dostęp do MongoDB i MongoDB Shell z dowolnego miejsca na komputerze programistycznym (Windows/Linux/macOS):
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 środowiskowejPATH
. - Windows: MongoDB Shell (mongosh.exe) jest zainstalowany w C:\Users\<user>\AppData\Local\Programs\mongosh. Dodaj wynikową ścieżkę dla
mongosh.exe
do zmiennej środowiskowejPATH
.
- macOS/Linux: Wybierz katalog, do którego chcesz wyodrębnić powłokę MongoDB. Dodaj wynikową ścieżkę dla
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 środowiskowejPATH
. - 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
.
- macOS/Linux: sprawdź katalog, w którym zainstalowano bazę danych MongoDB, zwykle w katalogu /usr/local/mongodb. Dodaj wynikową ścieżkę dla
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
.
- macOS/Linux: na przykład
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
.
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
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.
Books
Utwórz kolekcję przy użyciu następującego polecenia:db.createCollection('Books')
Zostanie wyświetlony następujący wynik:
{ "ok" : 1 }
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
ObjectId
pokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.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ść typuObjectId
dla każdego dokumentu.
Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core
Przejdź do Plik>Nowy>Projekt.
Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.
Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.
Wybierz platformę .NET 8.0 (obsługa długoterminowa) i wybierz pozycję Utwórz.
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
Dodaj katalog Models do katalogu głównego projektu.
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 typustring
zamiast struktury ObjectId . Mongo obsługuje konwersję zstring
naObjectId
.
Właściwość
BookName
jest oznaczona adnotacją z atrybutem[BsonElement]
. Wartość atrybutuName
reprezentuje nazwę właściwości w kolekcji MongoDB.
Dodawanie modelu konfiguracji
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": "*" }
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 przechowywaniaappsettings.json
wartości właściwości plikuBookStoreDatabase
. Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.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ść obiektuBookStoreDatabaseSettings
jest wypełniana właściwościąConnectionString
wBookStoreDatabase:ConnectionString
.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBookStoreDatabaseSettings
.using BookStoreApi.Models;
Dodaj usługę operacji CRUD
Dodaj katalog Services do katalogu głównego projektu.
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 doappsettings.json
wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.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ść odMongoClient
. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB,MongoClient
należy zarejestrować w DI z czasem życia singletona.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBooksService
.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łówekLocation
do odpowiedzi. NagłówekLocation
wskazuje URI nowo utworzonej książki.
Przetestuj internetowy interfejs API
Skompiluj i uruchom aplikację.
Przejdź do
https://localhost:<port>/api/books
, gdzie<port>
jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontroleraGet
. 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" } ]
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 jakoName
.
Aby spełnić powyższe wymagania, wprowadź następujące zmiany:
W
Program.cs
, dołącz następujący wyróżniony kod do wywołania metodyAddControllers
.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
klasyAuthor
serializuje się jakoAuthor
zamiastauthor
.W
Models/Book.cs
pliku dodaj adnotację doBookName
właściwości za pomocą atrybutu[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
Wartość
[JsonPropertyName]
atrybutuName
reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.Dodaj następujący kod na początku
Models/Book.cs
, aby rozwiązać odwołanie do atrybutu[JsonProperty]
:using System.Text.Json.Serialization;
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
Program Visual Studio 2022 z pakietem roboczym tworzenia aplikacji ASP.NET i aplikacji internetowych.
Konfigurowanie bazy danych MongoDB
Włącz dostęp do MongoDB i powłoki Mongo DB z dowolnego miejsca na maszynie deweloperskiej.
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
.Pobierz MongoDB Shell i wybierz katalog, do którego ma być wyodrębniony. Dodaj wynikową ścieżkę dla
mongosh.exe
do zmiennej środowiskowejPATH
.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.
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
.
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
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.
Books
Utwórz kolekcję przy użyciu następującego polecenia:db.createCollection('Books')
Zostanie wyświetlony następujący wynik:
{ "ok" : 1 }
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
ObjectId
pokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.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ść typuObjectId
dla każdego dokumentu.
Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core
Przejdź do Plik>Nowy>Projekt.
Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.
Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.
Wybierz strukturę .NET 7.0 (standardowe wsparcie) i wybierz pozycję Utwórz.
W menu Narzędzia wybierz NuGet Menedżer pakietów>Konsola Menedżera pakietów.
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
Dodaj katalog Models do katalogu głównego projektu.
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 typustring
zamiast struktury ObjectId . Mongo obsługuje konwersję zstring
naObjectId
.
Właściwość
BookName
jest oznaczona adnotacją z atrybutem[BsonElement]
. Wartość atrybutuName
reprezentuje nazwę właściwości w kolekcji MongoDB.
Dodawanie modelu konfiguracji
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": "*" }
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 przechowywaniaappsettings.json
wartości właściwości plikuBookStoreDatabase
. Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.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ść obiektuBookStoreDatabaseSettings
jest wypełniana właściwościąConnectionString
wBookStoreDatabase:ConnectionString
.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBookStoreDatabaseSettings
.using BookStoreApi.Models;
Dodaj usługę operacji CRUD
Dodaj katalog Services do katalogu głównego projektu.
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 doappsettings.json
wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.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ść odMongoClient
. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB,MongoClient
należy zarejestrować w DI z czasem życia singletona.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBooksService
.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łówekLocation
do odpowiedzi. NagłówekLocation
wskazuje URI nowo utworzonej książki.
Przetestuj internetowy interfejs API
Skompiluj i uruchom aplikację.
Przejdź do
https://localhost:<port>/api/books
, gdzie<port>
jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontroleraGet
. 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" } ]
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 jakoName
.
Aby spełnić powyższe wymagania, wprowadź następujące zmiany:
W
Program.cs
, dołącz następujący wyróżniony kod do wywołania metodyAddControllers
.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
klasyAuthor
serializuje się jakoAuthor
zamiastauthor
.W
Models/Book.cs
pliku dodaj adnotację doBookName
właściwości za pomocą atrybutu[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
Wartość
[JsonPropertyName]
atrybutuName
reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.Dodaj następujący kod na początku
Models/Book.cs
, aby rozwiązać odwołanie do atrybutu[JsonProperty]
:using System.Text.Json.Serialization;
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
- Program Visual Studio 2022 z pakietem roboczym tworzenia aplikacji ASP.NET i aplikacji internetowych.
- SDK .NET 6
Konfigurowanie bazy danych MongoDB
Włącz dostęp do MongoDB i powłoki Mongo DB z dowolnego miejsca na maszynie deweloperskiej.
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
.Pobierz MongoDB Shell i wybierz katalog, do którego ma być wyodrębniony. Dodaj wynikową ścieżkę dla
mongosh.exe
do zmiennej środowiskowejPATH
.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.
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
.
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
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.
Books
Utwórz kolekcję przy użyciu następującego polecenia:db.createCollection('Books')
Zostanie wyświetlony następujący wynik:
{ "ok" : 1 }
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
ObjectId
pokazane w poprzednim wyniku nie będą zgodne z wartościami wyświetlanymi w powłoce poleceń.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ść typuObjectId
dla każdego dokumentu.
Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core
Przejdź do Plik>Nowy>Projekt.
Wybierz typ projektu internetowego interfejsu API platformy ASP.NET Core, a następnie wybierz pozycję Dalej.
Nadaj projektowi nazwę BookStoreApi, a następnie wybierz pozycję Dalej.
Wybierz strukturę .NET 6.0 (obsługa długoterminowa) i wybierz pozycję Utwórz.
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
Dodaj katalog Models do katalogu głównego projektu.
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 typustring
zamiast struktury ObjectId . Mongo obsługuje konwersję zstring
naObjectId
.
Właściwość
BookName
jest oznaczona adnotacją z atrybutem[BsonElement]
. Wartość atrybutuName
reprezentuje nazwę właściwości w kolekcji MongoDB.
Dodawanie modelu konfiguracji
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": "*" }
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 przechowywaniaappsettings.json
wartości właściwości plikuBookStoreDatabase
. Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.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ść obiektuBookStoreDatabaseSettings
jest wypełniana właściwościąConnectionString
wBookStoreDatabase:ConnectionString
.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBookStoreDatabaseSettings
.using BookStoreApi.Models;
Dodaj usługę operacji CRUD
Dodaj katalog Services do katalogu głównego projektu.
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 doappsettings.json
wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.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ść odMongoClient
. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB,MongoClient
należy zarejestrować w DI z czasem życia singletona.Dodaj następujący kod na górze
Program.cs
, aby rozwiązać odwołanieBooksService
.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łówekLocation
do odpowiedzi. NagłówekLocation
wskazuje URI nowo utworzonej książki.
Przetestuj internetowy interfejs API
Skompiluj i uruchom aplikację.
Przejdź do
https://localhost:<port>/api/books
, gdzie<port>
jest automatycznie przypisanym numerem portu dla aplikacji, aby przetestować bezparametrową metodę akcji kontroleraGet
. 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" } ]
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 jakoName
.
Aby spełnić powyższe wymagania, wprowadź następujące zmiany:
W
Program.cs
, dołącz następujący wyróżniony kod do wywołania metodyAddControllers
.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
klasyAuthor
serializuje się jakoAuthor
zamiastauthor
.W
Models/Book.cs
pliku dodaj adnotację doBookName
właściwości za pomocą atrybutu[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
Wartość
[JsonPropertyName]
atrybutuName
reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.Dodaj następujący kod na początku
Models/Book.cs
, aby rozwiązać odwołanie do atrybutu[JsonProperty]
:using System.Text.Json.Serialization;
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
- .NET Core SDK 3.0 lub nowszy
- Visual Studio 2019 z pakietem roboczym ASP.NET i tworzenie aplikacji internetowych
- MongoDB
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.
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.
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>
Otwórz inne okno powłoki poleceń. Połącz się z domyślną testową bazą danych, uruchamiając następujące polecenie:
mongo
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.
Books
Utwórz kolekcję przy użyciu następującego polecenia:db.createCollection('Books')
Zostanie wyświetlony następujący wynik:
{ "ok" : 1 }
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.
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ść typuObjectId
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
Przejdź do Plik>Nowy>Projekt.
Wybierz typ projektu ASP.NET Core Web Application, a następnie wybierz pozycję Dalej.
Nadaj projektowi nazwę BooksApi i wybierz pozycję Utwórz.
Wybierz platformę docelową .NET Core i ASP.NET Core 3.0. Wybierz szablon projektu interfejsu API , a następnie wybierz pozycję Utwórz.
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
Dodaj katalog Models do katalogu głównego projektu.
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 typustring
zamiast struktury ObjectId . Mongo obsługuje konwersję zstring
naObjectId
.
Właściwość
BookName
jest oznaczona adnotacją z atrybutem[BsonElement]
. Wartość atrybutuName
reprezentuje nazwę właściwości w kolekcji MongoDB.
Dodawanie modelu konfiguracji
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" } } } }
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 przechowywaniaappsettings.json
wartości właściwości plikuBookstoreDatabaseSettings
. Nazwy właściwości JSON i C# są nazwane identycznie, aby ułatwić proces mapowania.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
obiektuConnectionString
jest wypełniana właściwościąBookstoreDatabaseSettings:ConnectionString
wappsettings.json
. - Interfejs
IBookstoreDatabaseSettings
jest rejestrowany w di z pojedynczym okresem istnienia usługi. Po wstrzyknięciu, wystąpienie interfejsu przekształca się w obiektBookstoreDatabaseSettings
.
- Instancja konfiguracji, z którą wiąże się sekcja pliku
Dodaj następujący kod na początku
Startup.cs
, aby rozwiązać odwołaniaBookstoreDatabaseSettings
iIBookstoreDatabaseSettings
.using BooksApi.Models;
Dodaj usługę operacji CRUD
Dodaj katalog Services do katalogu głównego projektu.
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 doappsettings.json
wartości konfiguracji, które zostały dodane w sekcji Dodaj model konfiguracji.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ść odMongoClient
. Zgodnie z oficjalnymi wytycznymi ponownego użycia klienta MongoDB,MongoClient
należy zarejestrować w DI z czasem życia singletona.Dodaj następujący kod na górze
Startup.cs
, aby rozwiązać odwołanieBookService
.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łówekLocation
do odpowiedzi. NagłówekLocation
wskazuje URI nowo utworzonej książki.
Przetestuj internetowy interfejs API
Skompiluj i uruchom aplikację.
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" } ]
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 jakoName
.
Aby spełnić powyższe wymagania, wprowadź następujące zmiany:
Json.NET został usunięty z platformy udostępnionej ASP.NET. Dodaj odwołanie do pakietu
Microsoft.AspNetCore.Mvc.NewtonsoftJson
.W
Startup.ConfigureServices
, dołącz następujący wyróżniony kod do wywołania metodyAddControllers
.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
Book
Author
serializuje się jakoAuthor
.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]
atrybutuName
reprezentuje nazwę właściwości w serializowanej odpowiedzi JSON internetowego interfejsu API.Dodaj następujący kod na początku
Models/Book.cs
, aby rozwiązać odwołanie do atrybutu[JsonProperty]
:using Newtonsoft.Json;
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ń:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C )
- Duende IdentityServer. Duende IdentityServer jest produktem innej firmy.
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: