Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão do .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão do .NET 9 deste artigo.
Por Pratik Khandelwal e Scott Addie
Este tutorial cria uma API Web que executa operações CRUD (Criar, Ler, Atualizar e Excluir) em um banco de dados NoSQL do MongoDB .
Neste tutorial, você aprenderá como:
- Configurar o MongoDB
- Criar um banco de dados do MongoDB
- Definir uma coleção e um esquema do MongoDB
- Executar operações CRUD do MongoDB a partir de uma API Web
- Personalizar a serialização JSON
Pré-requisitos
Visual Studio 2022 com a carga de trabalho de ASP.NET e desenvolvimento da Web .
Configurar o MongoDB
Habilite o acesso ao MongoDB e ao MongoDB Shell de qualquer lugar na máquina de desenvolvimento (Windows/Linux/macOS):
Baixe e instale o MongoDB Shell:
- macOS/Linux: Escolha um diretório para extrair o Shell do MongoDB. Adicione o caminho resultante para
mongosh
à variável de ambientePATH
. - Windows: O Shell do MongoDB (mongosh.exe) está instalado em C:\Users\<user>\AppData\Local\Programs\mongosh. Adicione o caminho resultante para
mongosh.exe
à variável de ambientePATH
.
- macOS/Linux: Escolha um diretório para extrair o Shell do MongoDB. Adicione o caminho resultante para
Baixe e instale o MongoDB:
- macOS/Linux: verifique o diretório no qual o MongoDB foi instalado, geralmente em /usr/local/mongodb. Adicione o caminho resultante para
mongodb
à variável de ambientePATH
. - Windows: O MongoDB é instalado em C:\Arquivos de Programas\MongoDB por padrão. Adicione C:\Program Files\MongoDB\Server\<version_number>\bin à variável de
PATH
ambiente.
- macOS/Linux: verifique o diretório no qual o MongoDB foi instalado, geralmente em /usr/local/mongodb. Adicione o caminho resultante para
Escolha um diretório de armazenamento de dados: Selecione um diretório em sua máquina de desenvolvimento para armazenar dados. Crie o diretório se não houver um. O MongoDB Shell não cria novos diretórios:
- macOS/Linux: Por exemplo,
/usr/local/var/mongodb
. - Windows: Por exemplo,
C:\\BooksData
.
- macOS/Linux: Por exemplo,
No shell de comando do sistema operacional (não no Shell do MongoDB), use o comando a seguir para se conectar ao MongoDB na porta padrão 27017. Substitua
<data_directory_path>
pelo diretório escolhido na etapa anterior.mongod --dbpath <data_directory_path>
Use o Shell do MongoDB instalado nas etapas a seguir para criar um banco de dados, criar coleções e armazenar documentos. Para obter mais informações sobre comandos do Shell do MongoDB, consulte mongosh
.
Abra uma instância do shell de comando do MongoDB iniciando
mongosh.exe
ou executando o seguinte comando no shell de comando:mongosh
No shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStore
Um banco de dados chamado BookStore será criado se ele ainda não existir. Se o banco de dados existir, a conexão dele será aberta para transações.
Crie uma coleção
Books
usando o seguinte comando:db.createCollection('Books')
O seguinte resultado é exibido:
{ "ok" : 1 }
Defina um esquema para a coleção
Books
e insira dois documentos usando o seguinte comando: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" }])
Um resultado semelhante ao apresentado a seguir será exibido:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Observação
Os
ObjectId
s mostrados no resultado anterior não corresponderão aos mostrados no terminal de comando.Visualize os documentos no banco de dados usando o seguinte comando:
db.Books.find().pretty()
Um resultado semelhante ao apresentado a seguir será exibido:
{ "_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" }
O esquema adiciona uma propriedade
_id
gerada automaticamente do tipoObjectId
para cada documento.
Criar o projeto da API Web do ASP.NET Core
- Vá para Arquivo>Novo>Projeto.
- Selecione o tipo de projeto da API Web ASP.NET Core e selecione Avançar.
- Nomeie o projeto BookStoreApi e selecione Avançar.
- Na diálogo de Informações adicionais:
- Confirme se o Framework é .NET 9.0 (Suporte Padrão).
- Verifique se a caixa de seleção de Usar controladores está marcada.
- Confirme se a caixa de seleção para habilitar o suporte ao OpenAPI está marcada.
- Selecione Criar.
Na janela Console do Gerenciador de Pacotes , navegue até a raiz do projeto. Execute o seguinte comando para instalar o driver .NET para MongoDB:
Install-Package MongoDB.Driver
Adicionar um modelo de entidade
Adicione um diretório Models à raiz do projeto.
Adicione uma
Book
classe ao diretório Models com o seguinte código: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!; }
Na classe anterior, a propriedade
Id
é:- Necessária para mapear o objeto CLR (Common Language Runtime) para a coleção do MongoDB.
- Anotada com
[BsonId]
para designar essa propriedade como a chave primária do documento. - Anotado com
[BsonRepresentation(BsonType.ObjectId)]
para permitir a passagem do parâmetro como tipostring
em vez de uma estrutura ObjectId. O Mongo processa a conversão destring
paraObjectId
.
A propriedade
BookName
é anotada com o atributo[BsonElement]
. O valor do atributo deName
representa o nome da propriedade da coleção do MongoDB.
Adicionar um modelo de configuração
Adicione os seguintes valores de configuração de banco de dados a
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Adicione uma
BookStoreDatabaseSettings
classe ao diretório Models com o seguinte código:namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
A classe anterior
BookStoreDatabaseSettings
é usada para armazenar os valores de propriedadeappsettings.json
do arquivoBookStoreDatabase
. Os nomes de propriedade JSON e C# são nomeados de forma idêntica para facilitar o processo de mapeamento.Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
No código anterior, a instância de configuração à qual a seção
appsettings.json
do arquivoBookStoreDatabase
se associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettings
de um objetoConnectionString
é populada com a propriedadeBookStoreDatabase:ConnectionString
noappsettings.json
.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBookStoreDatabaseSettings
:using BookStoreApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BooksService
classe ao diretório de Serviços com o seguinte código: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); }
No código anterior, uma instância
BookStoreDatabaseSettings
é recuperada da DI por meio da injeção de construtor. Essa técnica fornece acesso aosappsettings.json
valores de configuração que foram adicionados na seção Adicionar um modelo de configuração .Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
No código anterior, a classe
BooksService
é registrada com a DI para dar suporte à injeção de construtor nas classes consumidoras. O tempo de vida do serviço singleton é mais apropriado porqueBooksService
usa uma dependência direta deMongoClient
. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClient
deve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBooksService
:using BookStoreApi.Services;
A classe BooksService
usa os seguintes membros MongoDB.Driver
para executar operações CRUD em relação ao banco de dados:
MongoClient: lê a instância do servidor para executar operações de banco de dados. O construtor dessa classe é fornecido na cadeia de conexão do 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: representa o banco de dados Mongo para operações em execução. Este tutorial usa o método genérico GetCollection<TDocument>(collection) na interface para obter acesso aos dados em uma coleção específica. Execute operações CRUD em relação à coleção depois que esse método for chamado. Na chamada de método
GetCollection<TDocument>(collection)
:-
collection
representa o nome da coleção. -
TDocument
representa o tipo de objeto CLR armazenado na coleção.
-
GetCollection<TDocument>(collection)
retorna um objeto MongoCollection que representa a coleção. Neste tutorial, os seguintes métodos são invocados na coleção:
- DeleteOneAsync: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.
- Encontrar<TDocument>: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.
- InsertOneAsync: insere o objeto fornecido como um novo documento na coleção.
- ReplaceOneAsync: substitui o único documento que corresponde aos critérios de pesquisa fornecidos pelo objeto fornecido.
Adicionar um controlador
Adicione uma BooksController
classe ao diretório Controllers com o seguinte código:
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();
}
}
O controlador da API Web anterior:
- Usa a classe
BooksService
para executar operações CRUD. - Contém métodos de ação para dar suporte a solicitações GET, POST, PUT e DELETE HTTP.
- Chama CreatedAtAction no método de ação
Create
para retornar uma resposta HTTP 201. O código de status 201 é a resposta padrão para um método HTTP POST que cria um recurso no servidor.CreatedAtAction
também adiciona um cabeçalhoLocation
à resposta. O cabeçalhoLocation
especifica o URI do livro recém-criado.
Configurar opções de serialização JSON
Há dois detalhes a serem alterados sobre as respostas JSON retornadas na seção Testar a API Web :
- O uso de maiúsculas e minúsculas padrão dos nomes da propriedade deve ser alterado para corresponder ao uso de maiúsculas e minúsculas Pascal dos nomes de propriedade do objeto CLR.
- A propriedade
bookName
deve ser retornada comoName
.
Para cumprir os requisitos anteriores, faça as seguintes alterações:
Em
Program.cs
, encadeie o seguinte código realçado para a chamada de métodoAddControllers
: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);
Com a alteração anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto CLR. Por exemplo, a propriedade
Book
da classeAuthor
é serializada comoAuthor
ao invés deauthor
.No
Models/Book.cs
, anote a propriedadeBookName
com o atributo[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
O valor do atributo
[JsonPropertyName]
deName
representa o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cs
para resolver a referência[JsonProperty]
do atributo:using System.Text.Json.Serialization;
Repita as etapas definidas na seção Testar a API Web . Observe a diferença em nomes de propriedade JSON.
Testar a API Web
Este tutorial usa o Gerenciador de Pontos de Extremidade e os arquivos .http para testar a API.
Compile e execute o aplicativo.
No Explorador de Endpoints, clique com o botão direito do mouse no endpoint GET
/api/books
primeiro e selecione Gerar solicitação.O conteúdo a seguir é adicionado ao
BookStoreApi.http
arquivo. Se essa for a primeira vez que uma solicitação é gerada, o arquivo é criado na raiz do projeto.@BookStoreApi_HostAddress = https://localhost:<port> GET {{BookStoreApi_HostAddress}}/api/books ###
O número da porta já deve ser definido como a porta usada pelo aplicativo, por exemplo,
https://localhost:56874
. Se esse não for o caso, você poderá encontrar o número da porta na janela de saída quando iniciar o aplicativo.Selecione o link Enviar solicitação acima da nova
GET
linha de solicitação.A solicitação GET é enviada ao aplicativo e a resposta é exibida no painel Resposta .
O corpo da resposta apresenta o resultado JSON que contém as entradas do livro semelhantes a estas:
[ { "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" } ]
Para recuperar um único livro, clique com o botão direito do
/api/books/{id}, params (string id)
mouse no ponto de extremidade GET no Gerenciador de Pontos de Extremidade e selecione Gerar solicitação.O seguinte conteúdo é acrescentado ao
BookStoreApi.http
arquivo:@id=string GET {{BookStoreApi_HostAddress}}/api/books/{{id}} ###
Substitua
id
a variável por uma das IDs retornadas da solicitação anterior, por exemplo:@id="61a6058e6c43f32854e51f52" GET {{BookStoreApi_HostAddress}}/api/books/{{id}} ###
Selecione o link Enviar solicitação acima da nova
GET
linha de solicitação.A solicitação GET é enviada ao aplicativo e a resposta é exibida no painel Resposta .
O corpo da resposta apresenta um JSON semelhante ao seguinte:
{ "Id": "61a6058e6c43f32854e51f52", "Name": "Clean Code", "Price": 43.15, "Category": "Computers", "Author": "Robert C. Martin" }
Para testar o ponto de extremidade POST, clique com o botão direito do mouse no
/api/books
ponto de extremidade POST e selecione Gerar solicitação.O seguinte conteúdo é adicionado ao arquivo
BookStoreApi.http
:POST {{BookStoreApi_HostAddress}}/api/books Content-Type: application/json { //Book } ###
Substitua o comentário do Livro por um objeto de livro, como o corpo da solicitação JSON:
POST {{BookStoreApi_HostAddress}}/api/books Content-Type: application/json { "Name": "The Pragmatic Programmer", "Price": 49.99, "Category": "Computers", "Author": "Andy Hunt" } ###
Selecione o link Enviar solicitação acima da linha de solicitação
POST
.A solicitação POST é enviada ao aplicativo e a resposta é exibida no painel Resposta . A resposta deve incluir o livro recém-criado com sua ID atribuída.
Por fim, para excluir um livro, clique com o botão direito no endpoint
/api/books/{id}, params (string id)
e selecione Gerar solicitação.O seguinte conteúdo é acrescentado ao
BookStoreApi.http
arquivo:DELETE {{BookStoreApi_HostAddress}}/api/Books/{{id}} ###
Substitua a
id
variável por uma das IDs retornadas da solicitação anterior e clique em Enviar solicitação. Por exemplo:DELETE {{BookStoreApi_HostAddress}}/api/Books/67f417517ce1b36aeab71236 ###
Adicionar suporte de autenticação a uma API Web
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Servidor Duende Identity
O Duende Identity Server é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Identity Server habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Portal de Federação
Importante
O Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para obter mais informações, consulte Migrar do ASP.NET Core no .NET 5 para o .NET 6.
Para obter mais informações, consulte a documentação do Duende Identity Server (site do Duende Software).
Recursos adicionais
Este tutorial cria uma API Web que executa operações CRUD (Criar, Ler, Atualizar e Excluir) em um banco de dados NoSQL do MongoDB .
Neste tutorial, você aprenderá como:
- Configurar o MongoDB
- Criar um banco de dados do MongoDB
- Definir uma coleção e um esquema do MongoDB
- Executar operações CRUD do MongoDB a partir de uma API Web
- Personalizar a serialização JSON
Pré-requisitos
Visual Studio 2022 com a carga de trabalho de ASP.NET e desenvolvimento da Web .
Configurar o MongoDB
Habilite o acesso ao MongoDB e ao MongoDB Shell de qualquer lugar na máquina de desenvolvimento (Windows/Linux/macOS):
Baixe e instale o MongoDB Shell:
- macOS/Linux: Escolha um diretório para extrair o Shell do MongoDB. Adicione o caminho resultante para
mongosh
à variável de ambientePATH
. - Windows: O Shell do MongoDB (mongosh.exe) está instalado em C:\Users\<user>\AppData\Local\Programs\mongosh. Adicione o caminho resultante para
mongosh.exe
à variável de ambientePATH
.
- macOS/Linux: Escolha um diretório para extrair o Shell do MongoDB. Adicione o caminho resultante para
Baixe e instale o MongoDB:
- macOS/Linux: verifique o diretório no qual o MongoDB foi instalado, geralmente em /usr/local/mongodb. Adicione o caminho resultante para
mongodb
à variável de ambientePATH
. - Windows: O MongoDB é instalado em C:\Arquivos de Programas\MongoDB por padrão. Adicione C:\Program Files\MongoDB\Server\<version_number>\bin à variável de
PATH
ambiente.
- macOS/Linux: verifique o diretório no qual o MongoDB foi instalado, geralmente em /usr/local/mongodb. Adicione o caminho resultante para
Escolha um diretório de armazenamento de dados: Selecione um diretório em sua máquina de desenvolvimento para armazenar dados. Crie o diretório se não houver um. O MongoDB Shell não cria novos diretórios:
- macOS/Linux: Por exemplo,
/usr/local/var/mongodb
. - Windows: Por exemplo,
C:\\BooksData
.
- macOS/Linux: Por exemplo,
No shell de comando do sistema operacional (não no Shell do MongoDB), use o comando a seguir para se conectar ao MongoDB na porta padrão 27017. Substitua
<data_directory_path>
pelo diretório escolhido na etapa anterior.mongod --dbpath <data_directory_path>
Use o Shell do MongoDB instalado nas etapas a seguir para criar um banco de dados, criar coleções e armazenar documentos. Para obter mais informações sobre comandos do Shell do MongoDB, consulte mongosh
.
Abra uma instância do shell de comando do MongoDB iniciando
mongosh.exe
ou executando o seguinte comando no shell de comando:mongosh
No shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStore
Um banco de dados chamado BookStore será criado se ele ainda não existir. Se o banco de dados existir, a conexão dele será aberta para transações.
Crie uma coleção
Books
usando o seguinte comando:db.createCollection('Books')
O seguinte resultado é exibido:
{ "ok" : 1 }
Defina um esquema para a coleção
Books
e insira dois documentos usando o seguinte comando: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" }])
Um resultado semelhante ao apresentado a seguir será exibido:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Observação
Os
ObjectId
s mostrados no resultado anterior não corresponderão aos mostrados no terminal de comando.Visualize os documentos no banco de dados usando o seguinte comando:
db.Books.find().pretty()
Um resultado semelhante ao apresentado a seguir será exibido:
{ "_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" }
O esquema adiciona uma propriedade
_id
gerada automaticamente do tipoObjectId
para cada documento.
Criar o projeto da API Web do ASP.NET Core
Vá para Arquivo>Novo>Projeto.
Selecione o tipo de projeto da API Web ASP.NET Core e selecione Avançar.
Nomeie o projeto BookStoreApi e selecione Avançar.
Selecione a estrutura .NET 8.0 (suporte a longo prazo) e selecione Criar.
Na janela Console do Gerenciador de Pacotes , navegue até a raiz do projeto. Execute o seguinte comando para instalar o driver .NET para MongoDB:
Install-Package MongoDB.Driver
Adicionar um modelo de entidade
Adicione um diretório Models à raiz do projeto.
Adicione uma
Book
classe ao diretório Models com o seguinte código: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!; }
Na classe anterior, a propriedade
Id
é:- Necessária para mapear o objeto CLR (Common Language Runtime) para a coleção do MongoDB.
- Anotada com
[BsonId]
para designar essa propriedade como a chave primária do documento. - Anotado com
[BsonRepresentation(BsonType.ObjectId)]
para permitir a passagem do parâmetro como tipostring
em vez de uma estrutura ObjectId. O Mongo processa a conversão destring
paraObjectId
.
A propriedade
BookName
é anotada com o atributo[BsonElement]
. O valor do atributo deName
representa o nome da propriedade da coleção do MongoDB.
Adicionar um modelo de configuração
Adicione os seguintes valores de configuração de banco de dados a
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Adicione uma
BookStoreDatabaseSettings
classe ao diretório Models com o seguinte código:namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
A classe anterior
BookStoreDatabaseSettings
é usada para armazenar os valores de propriedadeappsettings.json
do arquivoBookStoreDatabase
. Os nomes de propriedade JSON e C# são nomeados de forma idêntica para facilitar o processo de mapeamento.Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
No código anterior, a instância de configuração à qual a seção
appsettings.json
do arquivoBookStoreDatabase
se associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettings
de um objetoConnectionString
é populada com a propriedadeBookStoreDatabase:ConnectionString
noappsettings.json
.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBookStoreDatabaseSettings
:using BookStoreApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BooksService
classe ao diretório de Serviços com o seguinte código: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); }
No código anterior, uma instância
BookStoreDatabaseSettings
é recuperada da DI por meio da injeção de construtor. Essa técnica fornece acesso aosappsettings.json
valores de configuração que foram adicionados na seção Adicionar um modelo de configuração .Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
No código anterior, a classe
BooksService
é registrada com a DI para dar suporte à injeção de construtor nas classes consumidoras. O tempo de vida do serviço singleton é mais apropriado porqueBooksService
usa uma dependência direta deMongoClient
. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClient
deve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBooksService
:using BookStoreApi.Services;
A classe BooksService
usa os seguintes membros MongoDB.Driver
para executar operações CRUD em relação ao banco de dados:
MongoClient: lê a instância do servidor para executar operações de banco de dados. O construtor dessa classe é fornecido na cadeia de conexão do 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: representa o banco de dados Mongo para operações em execução. Este tutorial usa o método genérico GetCollection<TDocument>(collection) na interface para obter acesso aos dados em uma coleção específica. Execute operações CRUD em relação à coleção depois que esse método for chamado. Na chamada de método
GetCollection<TDocument>(collection)
:-
collection
representa o nome da coleção. -
TDocument
representa o tipo de objeto CLR armazenado na coleção.
-
GetCollection<TDocument>(collection)
retorna um objeto MongoCollection que representa a coleção. Neste tutorial, os seguintes métodos são invocados na coleção:
- DeleteOneAsync: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.
- Encontrar<TDocument>: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.
- InsertOneAsync: insere o objeto fornecido como um novo documento na coleção.
- ReplaceOneAsync: substitui o único documento que corresponde aos critérios de pesquisa fornecidos pelo objeto fornecido.
Adicionar um controlador
Adicione uma BooksController
classe ao diretório Controllers com o seguinte código:
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();
}
}
O controlador da API Web anterior:
- Usa a classe
BooksService
para executar operações CRUD. - Contém métodos de ação para dar suporte a solicitações GET, POST, PUT e DELETE HTTP.
- Chama CreatedAtAction no método de ação
Create
para retornar uma resposta HTTP 201. O código de status 201 é a resposta padrão para um método HTTP POST que cria um recurso no servidor.CreatedAtAction
também adiciona um cabeçalhoLocation
à resposta. O cabeçalhoLocation
especifica o URI do livro recém-criado.
Testar a API Web
Compile e execute o aplicativo.
Navegue até
https://localhost:<port>/api/books
, onde<port>
é o número da porta atribuído automaticamente para o aplicativo, para testar o método de açãoGet
sem parâmetros do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:[ { "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" } ]
Navegue até
https://localhost:<port>/api/books/{id here}
para testar o método de açãoGet
sobrecarregado do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurar opções de serialização JSON
Há dois detalhes a serem alterados sobre as respostas JSON retornadas na seção Testar a API Web :
- O uso de maiúsculas e minúsculas padrão dos nomes da propriedade deve ser alterado para corresponder ao uso de maiúsculas e minúsculas Pascal dos nomes de propriedade do objeto CLR.
- A propriedade
bookName
deve ser retornada comoName
.
Para cumprir os requisitos anteriores, faça as seguintes alterações:
Em
Program.cs
, encadeie o seguinte código realçado para a chamada de métodoAddControllers
: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);
Com a alteração anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto CLR. Por exemplo, a propriedade
Book
da classeAuthor
é serializada comoAuthor
ao invés deauthor
.No
Models/Book.cs
, anote a propriedadeBookName
com o atributo[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
O valor do atributo
[JsonPropertyName]
deName
representa o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cs
para resolver a referência[JsonProperty]
do atributo:using System.Text.Json.Serialization;
Repita as etapas definidas na seção Testar a API Web . Observe a diferença em nomes de propriedade JSON.
Adicionar suporte de autenticação a uma API Web
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Servidor Duende Identity
O Duende Identity Server é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Identity Server habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Portal de Federação
Importante
O Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para obter mais informações, consulte Migrar do ASP.NET Core no .NET 5 para o .NET 6.
Para obter mais informações, consulte a documentação do Duende Identity Server (site do Duende Software).
Recursos adicionais
Este tutorial cria uma API Web que executa operações CRUD (Criar, Ler, Atualizar e Excluir) em um banco de dados NoSQL do MongoDB .
Neste tutorial, você aprenderá como:
- Configurar o MongoDB
- Criar um banco de dados do MongoDB
- Definir uma coleção e um esquema do MongoDB
- Executar operações CRUD do MongoDB a partir de uma API Web
- Personalizar a serialização JSON
Pré-requisitos
Visual Studio 2022 com a carga de trabalho de ASP.NET e desenvolvimento da Web .
Configurar o MongoDB
Habilite o acesso ao Shell do MongoDB e do Mongo DB de qualquer lugar no computador de desenvolvimento:
No Windows, o MongoDB é instalado em C:\Arquivos de Programas\MongoDB por padrão. Adicione C:\Program Files\MongoDB\Server\<version_number>\bin à variável de
PATH
ambiente.Baixe o Shell do MongoDB e escolha um diretório para o qual extraí-lo. Adicione o caminho resultante para
mongosh.exe
à variável de ambientePATH
.Escolha um diretório no seu computador de desenvolvimento para armazenar os dados. Por exemplo, C:\BooksData no Windows. Crie o diretório se não houver um. O Shell do mongo não cria novos diretórios.
No shell de comando do sistema operacional (não no Shell do MongoDB), use o comando a seguir para se conectar ao MongoDB na porta padrão 27017. Substitua
<data_directory_path>
pelo diretório escolhido na etapa anterior.mongod --dbpath <data_directory_path>
Use o Shell do MongoDB instalado nas etapas a seguir para criar um banco de dados, criar coleções e armazenar documentos. Para obter mais informações sobre comandos do Shell do MongoDB, consulte mongosh
.
Abra uma instância do shell de comando do MongoDB iniciando
mongosh.exe
ou executando o seguinte comando no shell de comando:mongosh
No shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStore
Um banco de dados chamado BookStore será criado se ele ainda não existir. Se o banco de dados existir, a conexão dele será aberta para transações.
Crie uma coleção
Books
usando o seguinte comando:db.createCollection('Books')
O seguinte resultado é exibido:
{ "ok" : 1 }
Defina um esquema para a coleção
Books
e insira dois documentos usando o seguinte comando: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" }])
Um resultado semelhante ao apresentado a seguir será exibido:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Observação
Os
ObjectId
s mostrados no resultado anterior não corresponderão aos mostrados no terminal de comando.Visualize os documentos no banco de dados usando o seguinte comando:
db.Books.find().pretty()
Um resultado semelhante ao apresentado a seguir será exibido:
{ "_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" }
O esquema adiciona uma propriedade
_id
gerada automaticamente do tipoObjectId
para cada documento.
Criar o projeto da API Web do ASP.NET Core
Vá para Arquivo>Novo>Projeto.
Selecione o tipo de projeto da API Web ASP.NET Core e selecione Avançar.
Nomeie o projeto BookStoreApi e selecione Avançar.
Selecione a estrutura .NET 7.0 (Suporte a Termos Padrão) e selecione Criar.
No menu Ferramentas, selecione Gerenciador de Pacotes NuGet>Console do Gerenciador de Pacotes.
Na janela Console do Gerenciador de Pacotes , navegue até a raiz do projeto. Execute o seguinte comando para instalar o driver .NET para MongoDB:
Install-Package MongoDB.Driver
Adicionar um modelo de entidade
Adicione um diretório Models à raiz do projeto.
Adicione uma
Book
classe ao diretório Models com o seguinte código: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!; }
Na classe anterior, a propriedade
Id
é:- Necessária para mapear o objeto CLR (Common Language Runtime) para a coleção do MongoDB.
- Anotada com
[BsonId]
para designar essa propriedade como a chave primária do documento. - Anotado com
[BsonRepresentation(BsonType.ObjectId)]
para permitir a passagem do parâmetro como tipostring
em vez de uma estrutura ObjectId. O Mongo processa a conversão destring
paraObjectId
.
A propriedade
BookName
é anotada com o atributo[BsonElement]
. O valor do atributo deName
representa o nome da propriedade da coleção do MongoDB.
Adicionar um modelo de configuração
Adicione os seguintes valores de configuração de banco de dados a
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Adicione uma
BookStoreDatabaseSettings
classe ao diretório Models com o seguinte código:namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
A classe anterior
BookStoreDatabaseSettings
é usada para armazenar os valores de propriedadeappsettings.json
do arquivoBookStoreDatabase
. Os nomes de propriedade JSON e C# são nomeados de forma idêntica para facilitar o processo de mapeamento.Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
No código anterior, a instância de configuração à qual a seção
appsettings.json
do arquivoBookStoreDatabase
se associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettings
de um objetoConnectionString
é populada com a propriedadeBookStoreDatabase:ConnectionString
noappsettings.json
.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBookStoreDatabaseSettings
:using BookStoreApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BooksService
classe ao diretório de Serviços com o seguinte código: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); }
No código anterior, uma instância
BookStoreDatabaseSettings
é recuperada da DI por meio da injeção de construtor. Essa técnica fornece acesso aosappsettings.json
valores de configuração que foram adicionados na seção Adicionar um modelo de configuração .Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
No código anterior, a classe
BooksService
é registrada com a DI para dar suporte à injeção de construtor nas classes consumidoras. O tempo de vida do serviço singleton é mais apropriado porqueBooksService
usa uma dependência direta deMongoClient
. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClient
deve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBooksService
:using BookStoreApi.Services;
A classe BooksService
usa os seguintes membros MongoDB.Driver
para executar operações CRUD em relação ao banco de dados:
MongoClient: lê a instância do servidor para executar operações de banco de dados. O construtor desta classe recebe a string de conexão do 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: representa o banco de dados Mongo para operações em execução. Este tutorial usa o método genérico GetCollection<TDocument>(collection) na interface para obter acesso aos dados em uma coleção específica. Execute operações CRUD em relação à coleção depois que esse método for chamado. Na chamada de método
GetCollection<TDocument>(collection)
:-
collection
representa o nome da coleção. -
TDocument
representa o tipo de objeto CLR armazenado na coleção.
-
GetCollection<TDocument>(collection)
retorna um objeto MongoCollection que representa a coleção. Neste tutorial, os seguintes métodos são invocados na coleção:
- DeleteOneAsync: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.
- Encontrar<TDocument>: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.
- InsertOneAsync: insere o objeto fornecido como um novo documento na coleção.
- ReplaceOneAsync: substitui o único documento que corresponde aos critérios de pesquisa fornecidos pelo objeto fornecido.
Adicionar um controlador
Adicione uma BooksController
classe ao diretório Controllers com o seguinte código:
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();
}
}
O controlador da API Web anterior:
- Usa a classe
BooksService
para executar operações CRUD. - Contém métodos de ação para dar suporte a solicitações GET, POST, PUT e DELETE HTTP.
- Chama CreatedAtAction no método de ação
Create
para retornar uma resposta HTTP 201. O código de status 201 é a resposta padrão para um método HTTP POST que cria um recurso no servidor.CreatedAtAction
também adiciona um cabeçalhoLocation
à resposta. O cabeçalhoLocation
especifica o URI do livro recém-criado.
Testar a API Web
Compile e execute o aplicativo.
Navegue até
https://localhost:<port>/api/books
, onde<port>
é o número da porta atribuído automaticamente para o aplicativo, para testar o método de açãoGet
sem parâmetros do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:[ { "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" } ]
Navegue até
https://localhost:<port>/api/books/{id here}
para testar o método de açãoGet
sobrecarregado do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurar opções de serialização JSON
Há dois detalhes a serem alterados sobre as respostas JSON retornadas na seção Testar a API Web :
- O uso de maiúsculas e minúsculas padrão dos nomes da propriedade deve ser alterado para corresponder ao uso de maiúsculas e minúsculas Pascal dos nomes de propriedade do objeto CLR.
- A propriedade
bookName
deve ser retornada comoName
.
Para cumprir os requisitos anteriores, faça as seguintes alterações:
Em
Program.cs
, encadeie o seguinte código realçado para a chamada de métodoAddControllers
: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);
Com a alteração anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto CLR. Por exemplo, a propriedade
Book
da classeAuthor
é serializada comoAuthor
ao invés deauthor
.No
Models/Book.cs
, anote a propriedadeBookName
com o atributo[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
O valor do atributo
[JsonPropertyName]
deName
representa o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cs
para resolver a referência[JsonProperty]
do atributo:using System.Text.Json.Serialization;
Repita as etapas definidas na seção Testar a API Web . Observe a diferença em nomes de propriedade JSON.
Adicionar suporte de autenticação a uma API Web
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Servidor Duende Identity
O Duende Identity Server é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Identity Server habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Portal de Federação
Importante
O Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para obter mais informações, consulte Migrar do ASP.NET Core no .NET 5 para o .NET 6.
Para obter mais informações, consulte a documentação do Duende Identity Server (site do Duende Software).
Recursos adicionais
Este tutorial cria uma API Web que executa operações CRUD (Criar, Ler, Atualizar e Excluir) em um banco de dados NoSQL do MongoDB .
Neste tutorial, você aprenderá como:
- Configurar o MongoDB
- Criar um banco de dados do MongoDB
- Definir uma coleção e um esquema do MongoDB
- Executar operações CRUD do MongoDB a partir de uma API Web
- Personalizar a serialização JSON
Pré-requisitos
- Visual Studio 2022 com a carga de trabalho de ASP.NET e desenvolvimento da Web .
- SDK do .NET 6
Configurar o MongoDB
Habilite o acesso ao Shell do MongoDB e do Mongo DB de qualquer lugar no computador de desenvolvimento:
No Windows, o MongoDB é instalado em C:\Arquivos de Programas\MongoDB por padrão. Adicione C:\Program Files\MongoDB\Server\<version_number>\bin à variável de
PATH
ambiente.Baixe o Shell do MongoDB e escolha um diretório para o qual extraí-lo. Adicione o caminho resultante para
mongosh.exe
à variável de ambientePATH
.Escolha um diretório no seu computador de desenvolvimento para armazenar os dados. Por exemplo, C:\BooksData no Windows. Crie o diretório se não houver um. O Shell do mongo não cria novos diretórios.
No shell de comando do sistema operacional (não no Shell do MongoDB), use o comando a seguir para se conectar ao MongoDB na porta padrão 27017. Substitua
<data_directory_path>
pelo diretório escolhido na etapa anterior.mongod --dbpath <data_directory_path>
Use o Shell do MongoDB instalado nas etapas a seguir para criar um banco de dados, criar coleções e armazenar documentos. Para obter mais informações sobre comandos do Shell do MongoDB, consulte mongosh
.
Abra uma instância do shell de comando do MongoDB iniciando
mongosh.exe
ou executando o seguinte comando no shell de comando:mongosh
No shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStore
Um banco de dados chamado BookStore será criado se ele ainda não existir. Se o banco de dados existir, a conexão dele será aberta para transações.
Crie uma coleção
Books
usando o seguinte comando:db.createCollection('Books')
O seguinte resultado é exibido:
{ "ok" : 1 }
Defina um esquema para a coleção
Books
e insira dois documentos usando o seguinte comando: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" }])
Um resultado semelhante ao apresentado a seguir será exibido:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Observação
Os
ObjectId
s mostrados no resultado anterior não corresponderão aos mostrados no terminal de comando.Visualize os documentos no banco de dados usando o seguinte comando:
db.Books.find().pretty()
Um resultado semelhante ao apresentado a seguir será exibido:
{ "_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" }
O esquema adiciona uma propriedade
_id
gerada automaticamente do tipoObjectId
para cada documento.
Criar o projeto da API Web do ASP.NET Core
Vá para Arquivo>Novo>Projeto.
Selecione o tipo de projeto da API Web ASP.NET Core e selecione Avançar.
Nomeie o projeto BookStoreApi e selecione Avançar.
Selecione a estrutura .NET 6.0 (suporte a longo prazo) e selecione Criar.
Na janela Console do Gerenciador de Pacotes , navegue até a raiz do projeto. Execute o seguinte comando para instalar o driver .NET para MongoDB:
Install-Package MongoDB.Driver
Adicionar um modelo de entidade
Adicione um diretório Models à raiz do projeto.
Adicione uma
Book
classe ao diretório Models com o seguinte código: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!; }
Na classe anterior, a propriedade
Id
é:- Necessária para mapear o objeto CLR (Common Language Runtime) para a coleção do MongoDB.
- Anotada com
[BsonId]
para designar essa propriedade como a chave primária do documento. - Anotado com
[BsonRepresentation(BsonType.ObjectId)]
para permitir a passagem do parâmetro como tipostring
em vez de uma estrutura ObjectId. O Mongo processa a conversão destring
paraObjectId
.
A propriedade
BookName
é anotada com o atributo[BsonElement]
. O valor do atributo deName
representa o nome da propriedade da coleção do MongoDB.
Adicionar um modelo de configuração
Adicione os seguintes valores de configuração de banco de dados a
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Adicione uma
BookStoreDatabaseSettings
classe ao diretório Models com o seguinte código:namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
A classe anterior
BookStoreDatabaseSettings
é usada para armazenar os valores de propriedadeappsettings.json
do arquivoBookStoreDatabase
. Os nomes de propriedade JSON e C# são nomeados de forma idêntica para facilitar o processo de mapeamento.Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
No código anterior, a instância de configuração à qual a seção
appsettings.json
do arquivoBookStoreDatabase
se associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettings
de um objetoConnectionString
é populada com a propriedadeBookStoreDatabase:ConnectionString
noappsettings.json
.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBookStoreDatabaseSettings
:using BookStoreApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BooksService
classe ao diretório de Serviços com o seguinte código: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); }
No código anterior, uma instância
BookStoreDatabaseSettings
é recuperada da DI por meio da injeção de construtor. Essa técnica fornece acesso aosappsettings.json
valores de configuração que foram adicionados na seção Adicionar um modelo de configuração .Adicione o código realçado a seguir a
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
No código anterior, a classe
BooksService
é registrada com a DI para dar suporte à injeção de construtor nas classes consumidoras. O tempo de vida do serviço singleton é mais apropriado porqueBooksService
usa uma dependência direta deMongoClient
. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClient
deve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cs
para resolver a referênciaBooksService
:using BookStoreApi.Services;
A classe BooksService
usa os seguintes membros MongoDB.Driver
para executar operações CRUD em relação ao banco de dados:
MongoClient: lê a instância do servidor para executar operações de banco de dados. O construtor desta classe recebe a string de conexão do 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: representa o banco de dados Mongo para operações em execução. Este tutorial usa o método genérico GetCollection<TDocument>(collection) na interface para obter acesso aos dados em uma coleção específica. Execute operações CRUD em relação à coleção depois que esse método for chamado. Na chamada de método
GetCollection<TDocument>(collection)
:-
collection
representa o nome da coleção. -
TDocument
representa o tipo de objeto CLR armazenado na coleção.
-
GetCollection<TDocument>(collection)
retorna um objeto MongoCollection que representa a coleção. Neste tutorial, os seguintes métodos são invocados na coleção:
- DeleteOneAsync: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.
- Encontrar<TDocument>: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.
- InsertOneAsync: insere o objeto fornecido como um novo documento na coleção.
- ReplaceOneAsync: substitui o único documento que corresponde aos critérios de pesquisa fornecidos pelo objeto fornecido.
Adicionar um controlador
Adicione uma BooksController
classe ao diretório Controllers com o seguinte código:
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();
}
}
O controlador da API Web anterior:
- Usa a classe
BooksService
para executar operações CRUD. - Contém métodos de ação para dar suporte a solicitações GET, POST, PUT e DELETE HTTP.
- Chama CreatedAtAction no método de ação
Create
para retornar uma resposta HTTP 201. O código de status 201 é a resposta padrão para um método HTTP POST que cria um recurso no servidor.CreatedAtAction
também adiciona um cabeçalhoLocation
à resposta. O cabeçalhoLocation
especifica o URI do livro recém-criado.
Testar a API Web
Compile e execute o aplicativo.
Navegue até
https://localhost:<port>/api/books
, onde<port>
é o número da porta atribuído automaticamente para o aplicativo, para testar o método de açãoGet
sem parâmetros do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:[ { "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" } ]
Navegue até
https://localhost:<port>/api/books/{id here}
para testar o método de açãoGet
sobrecarregado do controlador. Uma resposta JSON semelhante à apresentada a seguir será exibida:{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurar opções de serialização JSON
Há dois detalhes a serem alterados sobre as respostas JSON retornadas na seção Testar a API Web :
- O uso de maiúsculas e minúsculas padrão dos nomes da propriedade deve ser alterado para corresponder ao uso de maiúsculas e minúsculas Pascal dos nomes de propriedade do objeto CLR.
- A propriedade
bookName
deve ser retornada comoName
.
Para cumprir os requisitos anteriores, faça as seguintes alterações:
Em
Program.cs
, encadeie o seguinte código realçado para a chamada de métodoAddControllers
: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);
Com a alteração anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto CLR. Por exemplo, a propriedade
Book
da classeAuthor
é serializada comoAuthor
ao invés deauthor
.No
Models/Book.cs
, anote a propriedadeBookName
com o atributo[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
O valor do atributo
[JsonPropertyName]
deName
representa o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cs
para resolver a referência[JsonProperty]
do atributo:using System.Text.Json.Serialization;
Repita as etapas definidas na seção Testar a API Web . Observe a diferença em nomes de propriedade JSON.
Adicionar suporte de autenticação a uma API Web
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Servidor Duende Identity
O Duende Identity Server é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Identity Server habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Portal de Federação
Importante
O Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para obter mais informações, consulte Migrar do ASP.NET Core no .NET 5 para o .NET 6.
Para obter mais informações, consulte a documentação do Duende Identity Server (site do Duende Software).
Recursos adicionais
Este tutorial cria uma API Web que executa operações CRUD (Criar, Ler, Atualizar e Excluir) em um banco de dados NoSQL do MongoDB .
Neste tutorial, você aprenderá como:
- Configurar o MongoDB
- Criar um banco de dados do MongoDB
- Definir uma coleção e um esquema do MongoDB
- Executar operações CRUD do MongoDB a partir de uma API Web
- Personalizar a serialização JSON
Exibir ou baixar o código de exemplo (como baixar)
Pré-requisitos
- SDK do .NET Core 3.0 ou posterior
- Visual Studio 2019 com a carga de trabalho de ASP.NET e desenvolvimento na Web
- MongoDB
Configurar o MongoDB
Se estiver usando o Windows, o MongoDB será instalado em C:\Arquivos de Programas\MongoDB por padrão. Adicione C:\Program Files\MongoDB\Server\<version_number>\bin à variável de Path
ambiente. Essa alteração possibilita o acesso ao MongoDB a partir de qualquer lugar em seu computador de desenvolvimento.
Use o Shell do mongo nas etapas a seguir para criar um banco de dados, fazer coleções e armazenar documentos. Para obter mais informações sobre comandos do Mongo Shell, consulte Trabalhando com o Shell do mongo.
Escolha um diretório no seu computador de desenvolvimento para armazenar os dados. Por exemplo, C:\BooksData no Windows. Crie o diretório se não houver um. O Shell do mongo não cria novos diretórios.
Abra um shell de comando. Execute o comando a seguir para se conectar ao MongoDB na porta padrão 27017. Lembre-se de substituir
<data_directory_path>
pelo diretório escolhido na etapa anterior.mongod --dbpath <data_directory_path>
Abra outra instância do shell de comando. Conecte-se ao banco de dados de testes padrão executando o seguinte comando:
mongo
Execute o seguinte comando em um shell de comando:
use BookstoreDb
Um banco de dados chamado BookstoreDb será criado se ele ainda não existir. Se o banco de dados existir, a conexão dele será aberta para transações.
Crie uma coleção
Books
usando o seguinte comando:db.createCollection('Books')
O seguinte resultado é exibido:
{ "ok" : 1 }
Defina um esquema para a coleção
Books
e insira dois documentos usando o seguinte comando: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'}])
O seguinte resultado é exibido:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("5bfd996f7b8e48dc15ff215d"), ObjectId("5bfd996f7b8e48dc15ff215e") ] }
Observação
As IDs mostradas neste artigo não corresponderão às IDs de quando você executar esse exemplo.
Visualize os documentos no banco de dados usando o seguinte comando:
db.Books.find({}).pretty()
O seguinte resultado é exibido:
{ "_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" }
O esquema adiciona uma propriedade
_id
gerada automaticamente do tipoObjectId
para cada documento.
O banco de dados está pronto. Você pode começar a criar a API Web do ASP.NET Core.
Criar o projeto da API Web do ASP.NET Core
Vá para Arquivo>Novo>Projeto.
Selecione o tipo de projeto ASP.NET Aplicativo Web Principal e selecione Avançar.
Nomeie o projeto BooksApi e selecione Criar.
Selecione a estrutura de destino do .NET Core e o ASP.NET Core 3.0. Selecione o modelo de projeto de API e selecione Criar.
Visite a Galeria do NuGet: MongoDB.Driver para determinar a versão estável mais recente do driver .NET para MongoDB. Na janela Console do Gerenciador de Pacotes , navegue até a raiz do projeto. Execute o seguinte comando para instalar o driver .NET para MongoDB:
Install-Package MongoDB.Driver -Version {VERSION}
Adicionar um modelo de entidade
Adicione um diretório Models à raiz do projeto.
Adicione uma
Book
classe ao diretório Models com o seguinte código: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; } } }
Na classe anterior, a propriedade
Id
é:- Necessária para mapear o objeto CLR (Common Language Runtime) para a coleção do MongoDB.
- Anotada com
[BsonId]
para designar essa propriedade como a chave primária do documento. - Anotado com
[BsonRepresentation(BsonType.ObjectId)]
para permitir a passagem do parâmetro como tipostring
em vez de uma estrutura ObjectId. O Mongo processa a conversão destring
paraObjectId
.
A propriedade
BookName
é anotada com o atributo[BsonElement]
. O valor do atributo deName
representa o nome da propriedade da coleção do MongoDB.
Adicionar um modelo de configuração
Adicione os seguintes valores de configuração de banco de dados a
appsettings.json
:{ "BookstoreDatabaseSettings": { "BooksCollectionName": "Books", "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookstoreDb" }, "Logging": { "IncludeScopes": false, "Debug": { "LogLevel": { "Default": "Warning" } }, "Console": { "LogLevel": { "Default": "Warning" } } } }
Adicione um
BookstoreDatabaseSettings.cs
arquivo ao diretório Modelos com o seguinte código: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; } } }
A classe anterior
BookstoreDatabaseSettings
é usada para armazenar os valores de propriedadeappsettings.json
do arquivoBookstoreDatabaseSettings
. Os nomes de propriedade JSON e C# são nomeados de forma idêntica para facilitar o processo de mapeamento.Adicione o código realçado a seguir a
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(); }
No código anterior:
- A instância de configuração à qual a seção
appsettings.json
do arquivoBookstoreDatabaseSettings
é associada é registrada no contêiner de DI (Injeção de Dependência). Por exemplo, a propriedadeBookstoreDatabaseSettings
de um objetoConnectionString
é populada com a propriedadeBookstoreDatabaseSettings:ConnectionString
noappsettings.json
. - A
IBookstoreDatabaseSettings
interface é registrada em DI com um tempo de vida de serviço singleton. Quando inserida, a instância da interface é resolvida para um objetoBookstoreDatabaseSettings
.
- A instância de configuração à qual a seção
Adicione o seguinte código na parte superior do
Startup.cs
para resolver as referênciasBookstoreDatabaseSettings
eIBookstoreDatabaseSettings
:using BooksApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BookService
classe ao diretório de Serviços com o seguinte código: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); } }
No código anterior, uma instância
IBookstoreDatabaseSettings
é recuperada da DI por meio da injeção de construtor. Essa técnica fornece acesso aosappsettings.json
valores de configuração que foram adicionados na seção Adicionar um modelo de configuração .Adicione o código realçado a seguir a
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(); }
No código anterior, a classe
BookService
é registrada com a DI para dar suporte à injeção de construtor nas classes consumidoras. O tempo de vida do serviço singleton é mais apropriado porqueBookService
usa uma dependência direta deMongoClient
. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClient
deve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Startup.cs
para resolver a referênciaBookService
:using BooksApi.Services;
A classe BookService
usa os seguintes membros MongoDB.Driver
para executar operações CRUD em relação ao banco de dados:
MongoClient: lê a instância do servidor para executar operações de banco de dados. O construtor desta classe recebe a string de conexão do MongoDB.
public BookService(IBookstoreDatabaseSettings settings) { var client = new MongoClient(settings.ConnectionString); var database = client.GetDatabase(settings.DatabaseName); _books = database.GetCollection<Book>(settings.BooksCollectionName); }
IMongoDatabase: representa o banco de dados Mongo para operações em execução. Este tutorial usa o método genérico GetCollection<TDocument>(collection) na interface para obter acesso aos dados em uma coleção específica. Execute operações CRUD em relação à coleção depois que esse método for chamado. Na chamada de método
GetCollection<TDocument>(collection)
:-
collection
representa o nome da coleção. -
TDocument
representa o tipo de objeto CLR armazenado na coleção.
-
GetCollection<TDocument>(collection)
retorna um objeto MongoCollection que representa a coleção. Neste tutorial, os seguintes métodos são invocados na coleção:
- DeleteOne: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.
- Encontrar<TDocument>: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.
- InsertOne: insere o objeto fornecido como um novo documento na coleção.
- ReplaceOne: substitui o único documento que corresponde aos critérios de pesquisa fornecidos pelo objeto fornecido.
Adicionar um controlador
Adicione uma BooksController
classe ao diretório Controllers com o seguinte código:
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();
}
}
}
O controlador da API Web anterior:
- Usa a classe
BookService
para executar operações CRUD. - Contém métodos de ação para dar suporte a solicitações GET, POST, PUT e DELETE HTTP.
- Chama CreatedAtRoute no método de ação
Create
para retornar uma resposta HTTP 201. O código de status 201 é a resposta padrão para um método HTTP POST que cria um recurso no servidor.CreatedAtRoute
também adiciona um cabeçalhoLocation
à resposta. O cabeçalhoLocation
especifica o URI do livro recém-criado.
Testar a API Web
Compile e execute o aplicativo.
Navegue até
https://localhost:<port>/api/books
para testar o método de açãoGet
sem parâmetros do controlador. A seguinte resposta JSON é exibida:[ { "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" } ]
Navegue até
https://localhost:<port>/api/books/{id here}
para testar o método de açãoGet
sobrecarregado do controlador. A seguinte resposta JSON é exibida:{ "id":"{ID}", "bookName":"Clean Code", "price":43.15, "category":"Computers", "author":"Robert C. Martin" }
Configurar opções de serialização JSON
Há dois detalhes a serem alterados sobre as respostas JSON retornadas na seção Testar a API Web :
- O uso de maiúsculas e minúsculas padrão dos nomes da propriedade deve ser alterado para corresponder ao uso de maiúsculas e minúsculas Pascal dos nomes de propriedade do objeto CLR.
- A propriedade
bookName
deve ser retornada comoName
.
Para cumprir os requisitos anteriores, faça as seguintes alterações:
O JSON.NET foi removido da estrutura compartilhada do ASP.NET. Adicione uma referência de pacote para
Microsoft.AspNetCore.Mvc.NewtonsoftJson
.Em
Startup.ConfigureServices
, encadeie o seguinte código realçado para a chamada de métodoAddControllers
: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()); }
Com a alteração anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto CLR. Por exemplo, a propriedade
Book
da classeAuthor
é serializada comoAuthor
.No
Models/Book.cs
, anote a propriedadeBookName
com o atributo[JsonProperty]
a seguir:[BsonElement("Name")] [JsonProperty("Name")] public string BookName { get; set; }
O valor do atributo
[JsonProperty]
deName
representa o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cs
para resolver a referência[JsonProperty]
do atributo:using Newtonsoft.Json;
Repita as etapas definidas na seção Testar a API Web . Observe a diferença em nomes de propriedade JSON.
Adicionar suporte de autenticação a uma API Web
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. O IdentityServer da Duende é um produto de terceiros.
O Duende IdentityServer é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O IdentityServer da Duende habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Portal de Federação
Para obter mais informações, consulte Visão geral do Duende IdentityServer.
Para obter mais informações sobre outros provedores de autenticação, consulte as opções de autenticação do OSS da Comunidade para ASP.NET Core
Próximas etapas
Para saber mais sobre a criação de APIs Web do ASP.NET Core, confira os seguintes recursos: