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.
Note
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 10 deste artigo.
Warning
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 10 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
Prerequisites
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
PATHambiente.
- 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.exeou executando o seguinte comando no shell de comando:mongoshNo shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStoreUm 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
Booksusando o seguinte comando:db.createCollection('Books')O seguinte resultado é exibido:
{ "ok" : 1 }Defina um esquema para a coleção
Bookse 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") ] }Note
Os
ObjectIds 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
_idgerada automaticamente do tipoObjectIdpara 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
Bookclasse 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 tipostringem vez de uma estrutura ObjectId. O Mongo processa a conversão destringparaObjectId.
A propriedade
BookNameé anotada com o atributo[BsonElement]. O valor do atributo deNamerepresenta 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
BookStoreDatabaseSettingsclasse 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.jsondo 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.jsondo arquivoBookStoreDatabasese associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettingsde um objetoConnectionStringé populada com a propriedadeBookStoreDatabase:ConnectionStringnoappsettings.json.Adicione o seguinte código na parte superior do
Program.cspara 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
BooksServiceclasse 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.jsonvalores 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 porqueBooksServiceusa uma dependência direta deMongoClient. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClientdeve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cspara 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):-
collectionrepresenta o nome da coleção. -
TDocumentrepresenta 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
BooksServicepara 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
Createpara 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.CreatedAtActiontambém adiciona um cabeçalhoLocationà resposta. O cabeçalhoLocationespecifica 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
bookNamedeve 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
Bookda classeAuthoré serializada comoAuthorao invés deauthor.No
Models/Book.cs, anote a propriedadeBookNamecom o atributo[JsonPropertyName]:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;O valor do atributo
[JsonPropertyName]deNamerepresenta o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cspara 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/booksprimeiro e selecione Gerar solicitação.O conteúdo a seguir é adicionado ao
BookStoreApi.httparquivo. 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
GETlinha 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.httparquivo:@id=string GET {{BookStoreApi_HostAddress}}/api/books/{{id}} ###Substitua
ida 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
GETlinha 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/booksponto 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.httparquivo:DELETE {{BookStoreApi_HostAddress}}/api/Books/{{id}} ###Substitua a
idvariá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
Important
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
Prerequisites
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
PATHambiente.
- 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.exeou executando o seguinte comando no shell de comando:mongoshNo shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStoreUm 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
Booksusando o seguinte comando:db.createCollection('Books')O seguinte resultado é exibido:
{ "ok" : 1 }Defina um esquema para a coleção
Bookse 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") ] }Note
Os
ObjectIds 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
_idgerada automaticamente do tipoObjectIdpara 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
Bookclasse 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 tipostringem vez de uma estrutura ObjectId. O Mongo processa a conversão destringparaObjectId.
A propriedade
BookNameé anotada com o atributo[BsonElement]. O valor do atributo deNamerepresenta 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
BookStoreDatabaseSettingsclasse 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.jsondo 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.jsondo arquivoBookStoreDatabasese associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettingsde um objetoConnectionStringé populada com a propriedadeBookStoreDatabase:ConnectionStringnoappsettings.json.Adicione o seguinte código na parte superior do
Program.cspara 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
BooksServiceclasse 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.jsonvalores 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 porqueBooksServiceusa uma dependência direta deMongoClient. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClientdeve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cspara 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):-
collectionrepresenta o nome da coleção. -
TDocumentrepresenta 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
BooksServicepara 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
Createpara 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.CreatedAtActiontambém adiciona um cabeçalhoLocationà resposta. O cabeçalhoLocationespecifica 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çãoGetsem 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çãoGetsobrecarregado 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
bookNamedeve 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
Bookda classeAuthoré serializada comoAuthorao invés deauthor.No
Models/Book.cs, anote a propriedadeBookNamecom o atributo[JsonPropertyName]:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;O valor do atributo
[JsonPropertyName]deNamerepresenta o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cspara 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
Important
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
Prerequisites
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
PATHambiente.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.exeou executando o seguinte comando no shell de comando:mongoshNo shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStoreUm 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
Booksusando o seguinte comando:db.createCollection('Books')O seguinte resultado é exibido:
{ "ok" : 1 }Defina um esquema para a coleção
Bookse 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") ] }Note
Os
ObjectIds 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
_idgerada automaticamente do tipoObjectIdpara 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
Bookclasse 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 tipostringem vez de uma estrutura ObjectId. O Mongo processa a conversão destringparaObjectId.
A propriedade
BookNameé anotada com o atributo[BsonElement]. O valor do atributo deNamerepresenta 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
BookStoreDatabaseSettingsclasse 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.jsondo 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.jsondo arquivoBookStoreDatabasese associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettingsde um objetoConnectionStringé populada com a propriedadeBookStoreDatabase:ConnectionStringnoappsettings.json.Adicione o seguinte código na parte superior do
Program.cspara 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
BooksServiceclasse 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.jsonvalores 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 porqueBooksServiceusa uma dependência direta deMongoClient. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClientdeve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cspara 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):-
collectionrepresenta o nome da coleção. -
TDocumentrepresenta 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
BooksServicepara 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
Createpara 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.CreatedAtActiontambém adiciona um cabeçalhoLocationà resposta. O cabeçalhoLocationespecifica 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çãoGetsem 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çãoGetsobrecarregado 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
bookNamedeve 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
Bookda classeAuthoré serializada comoAuthorao invés deauthor.No
Models/Book.cs, anote a propriedadeBookNamecom o atributo[JsonPropertyName]:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;O valor do atributo
[JsonPropertyName]deNamerepresenta o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cspara 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
Important
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
Prerequisites
- 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
PATHambiente.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.exeou executando o seguinte comando no shell de comando:mongoshNo shell de comando, conecte-se ao banco de dados de teste padrão executando:
use BookStoreUm 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
Booksusando o seguinte comando:db.createCollection('Books')O seguinte resultado é exibido:
{ "ok" : 1 }Defina um esquema para a coleção
Bookse 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") ] }Note
Os
ObjectIds 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
_idgerada automaticamente do tipoObjectIdpara 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
Bookclasse 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 tipostringem vez de uma estrutura ObjectId. O Mongo processa a conversão destringparaObjectId.
A propriedade
BookNameé anotada com o atributo[BsonElement]. O valor do atributo deNamerepresenta 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
BookStoreDatabaseSettingsclasse 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.jsondo 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.jsondo arquivoBookStoreDatabasese associa é registrada no contêiner de Injeção de Dependência (DI). Por exemplo, a propriedadeBookStoreDatabaseSettingsde um objetoConnectionStringé populada com a propriedadeBookStoreDatabase:ConnectionStringnoappsettings.json.Adicione o seguinte código na parte superior do
Program.cspara 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
BooksServiceclasse 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.jsonvalores 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 porqueBooksServiceusa uma dependência direta deMongoClient. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClientdeve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Program.cspara 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):-
collectionrepresenta o nome da coleção. -
TDocumentrepresenta 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
BooksServicepara 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
Createpara 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.CreatedAtActiontambém adiciona um cabeçalhoLocationà resposta. O cabeçalhoLocationespecifica 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çãoGetsem 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çãoGetsobrecarregado 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
bookNamedeve 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
Bookda classeAuthoré serializada comoAuthorao invés deauthor.No
Models/Book.cs, anote a propriedadeBookNamecom o atributo[JsonPropertyName]:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;O valor do atributo
[JsonPropertyName]deNamerepresenta o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cspara 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
Important
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)
Prerequisites
- 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:
mongoExecute o seguinte comando em um shell de comando:
use BookstoreDbUm 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
Booksusando o seguinte comando:db.createCollection('Books')O seguinte resultado é exibido:
{ "ok" : 1 }Defina um esquema para a coleção
Bookse 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") ] }Note
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
_idgerada automaticamente do tipoObjectIdpara 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
Bookclasse 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 tipostringem vez de uma estrutura ObjectId. O Mongo processa a conversão destringparaObjectId.
A propriedade
BookNameé anotada com o atributo[BsonElement]. O valor do atributo deNamerepresenta 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.csarquivo 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.jsondo 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.jsondo arquivoBookstoreDatabaseSettingsé associada é registrada no contêiner de DI (Injeção de Dependência). Por exemplo, a propriedadeBookstoreDatabaseSettingsde um objetoConnectionStringé populada com a propriedadeBookstoreDatabaseSettings:ConnectionStringnoappsettings.json. - A
IBookstoreDatabaseSettingsinterface é 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.cspara resolver as referênciasBookstoreDatabaseSettingseIBookstoreDatabaseSettings:using BooksApi.Models;
Adicionar um serviço de operações CRUD
Adicione um diretório de Serviços à raiz do projeto.
Adicione uma
BookServiceclasse 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.jsonvalores 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 porqueBookServiceusa uma dependência direta deMongoClient. De acordo com as diretrizes oficiais de reutilização do Cliente Mongo,MongoClientdeve ser registrado em DI com um tempo de vida de serviço singleton.Adicione o seguinte código na parte superior do
Startup.cspara 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):-
collectionrepresenta o nome da coleção. -
TDocumentrepresenta 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
BookServicepara 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
Createpara 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.CreatedAtRoutetambém adiciona um cabeçalhoLocationà resposta. O cabeçalhoLocationespecifica o URI do livro recém-criado.
Testar a API Web
Compile e execute o aplicativo.
Navegue até
https://localhost:<port>/api/bookspara testar o método de açãoGetsem 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çãoGetsobrecarregado 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
bookNamedeve 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
Bookda classeAuthoré serializada comoAuthor.No
Models/Book.cs, anote a propriedadeBookNamecom o atributo[JsonProperty]a seguir:[BsonElement("Name")] [JsonProperty("Name")] public string BookName { get; set; }O valor do atributo
[JsonProperty]deNamerepresenta o nome da propriedade da resposta JSON serializada da API Web.Adicione o seguinte código na parte superior do
Models/Book.cspara 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: