- 使用 ASP.NET Core 和 MongoDB 创建 Web APICreate a web API with ASP.NET Core and MongoDB
- 先决条件Prerequisites
- 配置 MongoDBConfigure MongoDB
- 创建 ASP.NET Core Web API 项目Create the ASP.NET Core web API project
- 添加实体模型Add an entity model
- 添加配置模型Add a configuration model
- 添加 CRUD 操作服务Add a CRUD operations service
- 添加控制器Add a controller
- 测试 Web APITest the web API
- 配置 JSON 序列化选项Configure JSON serialization options
- 先决条件Prerequisites
- 配置 MongoDBConfigure MongoDB
- 创建 ASP.NET Core Web API 项目Create the ASP.NET Core web API project
- 添加实体模型Add an entity model
- 添加配置模型Add a configuration model
- 添加 CRUD 操作服务Add a CRUD operations service
- 添加控制器Add a controller
- 测试 Web APITest the web API
- 配置 JSON 序列化选项Configure JSON serialization options
- 向 Web API 添加身份验证支持Add authentication support to a web API
- 后续步骤Next steps
使用 ASP.NET Core 和 MongoDB 创建 Web APICreate a web API with ASP.NET Core and MongoDB
本文内容
作者 Pratik Khandelwal 和 Scott Addie
本教程创建对 MongoDB NoSQL 数据库执行创建、读取、更新和删除 (CRUD) 操作的 Web API。
在本教程中,你将了解:
- 配置 MongoDB
- 创建 MongoDB 数据库
- 定义 MongoDB 集合和架构
- 从 Web API 执行 MongoDB CRUD 操作
- 自定义 JSON 序列化
先决条件Prerequisites
- .NET Core SDK 3.0 或更高版本
- Visual Studio 2019 与 ASP.NET 和 Web 开发 工作负载
- MongoDB
配置 MongoDBConfigure MongoDB
如果使用的是 Windows,MongoDB 将默认安装在 C:\Program Files\MongoDB 中。将 C:\Program Files\MongoDB\Server\<version_number>\bin 添加到 Path
环境变量中。通过此更改可以从开发计算机上的任意位置访问 MongoDB。
使用以下步骤中的 mongo Shell 可以创建数据库、创建集合和存储文档。有关 mongo Shell 命令的详细信息,请参阅使用 mongo Shell。
选择开发计算机上用于存储数据的目录。例如,Windows 上的 C:\BooksData 。创建目录(如果不存在)。mongo Shell 不会创建新目录。
打开命令行界面。运行以下命令以连接到默认端口 27017 上的 MongoDB。请记得将
<data_directory_path>
替换为上一步中选择的目录。
mongod --dbpath <data_directory_path>
- 打开另一个命令行界面实例。通过运行以下命令来连接到默认测试数据库:
mongo
- 在命令行界面中运行下面的命令:
use BookstoreDb
如果它不存在,则将创建名为 BookstoreDb 的数据库。如果该数据库存在,则将为事务打开其连接。
- 使用以下命令创建
Books
集合:
db.createCollection('Books')
显示以下结果:
{ "ok" : 1 }
- 使用以下命令定义
Books
集合的架构并插入两个文档:
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'}])
显示以下结果:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5bfd996f7b8e48dc15ff215d"),
ObjectId("5bfd996f7b8e48dc15ff215e")
]
}
备注
本文所示的 ID 与运行此示例时的 ID 不匹配。
- 使用以下命令查看数据库中的文档:
db.Books.find({}).pretty()
显示以下结果:
{
"_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"
}
该架构将为每个文档添加类型 ObjectId
的自动生成的 _id
属性。
数据库可供使用了。你可以开始创建 ASP.NET Core Web API。
创建 ASP.NET Core Web API 项目Create the ASP.NET Core web API project
转到“文件”>“新建”>“项目” 。
选择“ASP.NET Core Web 应用程序”项目类型,然后选择“下一步” 。
将项目命名为“BooksApi”,然后选择“创建” 。
选择“.NET Core” 目标框架和“ASP.NET Core 3.0” 。选择“API”项目模板,然后选择“创建” 。
访问 NuGet 库:MongoDB.Driver 来确定适用于 MongoDB 的 .NET 驱动程序的最新稳定版本。在“包管理器控制台” 窗口中,导航到项目根。运行以下命令以安装适用于 MongoDB 的 .NET 驱动程序:
Install-Package MongoDB.Driver -Version {VERSION}
- 在命令行界面中运行以下命令:
dotnet new webapi -o BooksApi
code BooksApi
将在 Visual Studio Code 中生成并打开以 .NET Core 为目标的新 ASP.NET Core Web API 项目。
状态栏的 OmniSharp 火焰图标变绿后,对话框将询问“'BooksApi' 缺少生成和调试所需的资产。 是否添加它们?”。选择 “是” 。
访问 NuGet 库:MongoDB.Driver 来确定适用于 MongoDB 的 .NET 驱动程序的最新稳定版本。打开“集成终端” 并导航到项目根。运行以下命令以安装适用于 MongoDB 的 .NET 驱动程序:
dotnet add BooksApi.csproj package MongoDB.Driver -v {VERSION}
- 转到“文件”>“新建解决方案”>“.NET Core”>“应用” 。
- 选择“ASP.NET Core Web API”C# 项目模板,然后选择“下一步” 。
- 从“目标框架”下拉列表中选择“.NET Core 3.0”,然后选择“下一步” 。
- 输入“BooksApi”作为“项目名称”,然后选择“创建” 。
- 在“解决方案” 面板中,右键单击项目的“依赖项” 节点,然后选择“添加包” 。
- 在搜索框中输入“MongoDB.Driver”,选择“MongoDB.Driver”包,然后选择“添加包” 。
- 在“许可证接受”对话框中,选择“接受”按钮 。
添加实体模型Add an entity model
将 Models 目录添加到项目根。
使用以下代码将
Book
类添加到 Models 目录:
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; }
}
}
在前面的类中,Id
属性:
- 需要在将公共语言运行时 (CLR) 对象映射到 MongoDB 集合时使用。
- 使用
[BsonId]
进行批注,以将此属性指定为文档的主键。 - 使用
[BsonRepresentation(BsonType.ObjectId)]
进行批注,以允许将参数作为类型string
而非 ObjectId 结构传递。Mongo 处理从string
到ObjectId
的转换。BookName
属性使用[BsonElement]
特性进行批注。Name
的属性值表示 MongoDB 集合中的属性名称。
添加配置模型Add a configuration model
- 向 appsettings.json 添加以下数据库配置值 :
{
"BookstoreDatabaseSettings": {
"BooksCollectionName": "Books",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "BookstoreDb"
},
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
- 使用以下代码将 BookstoreDatabaseSettings.cs 文件添加到 Models 目录 :
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; }
}
}
前面的 BookstoreDatabaseSettings
类用于存储 appsettings.json 文件的 BookstoreDatabaseSettings
属性值 。JSON 和 C# 具有相同的属性名称,目的是简化映射过程。
- 将以下突出显示的代码添加到
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();
}
在上述代码中:
- appsettings.json 文件的
BookstoreDatabaseSettings
部分绑定到的配置实例在依赖关系注入 (DI) 容器中注册 。例如,BookstoreDatabaseSettings
对象的ConnectionString
属性使用 appsettings.json 中的BookstoreDatabaseSettings:ConnectionString
属性进行填充 。 IBookstoreDatabaseSettings
接口使用单一实例服务生存期在 DI 中注册。在注入时,接口实例时将解析为BookstoreDatabaseSettings
对象。- 在 Startup.cs 顶部添加以下代码,以解析
BookstoreDatabaseSettings
和IBookstoreDatabaseSettings
引用 :
- 在 Startup.cs 顶部添加以下代码,以解析
using BooksApi.Models;
添加 CRUD 操作服务Add a CRUD operations service
将 Services 目录添加到项目根。
使用以下代码将
BookService
类添加到 Services 目录:
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);
}
}
上面的代码通过构造函数注入从 DI 检索 IBookstoreDatabaseSettings
实例。使用此方法可访问在添加配置模型部分添加的 appsettings.json 配置值 。
- 将以下突出显示的代码添加到
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();
}
上面的代码向 DI 注册了 BookService
类,以支持消费类中的构造函数注入。单一实例服务生存期是最合适的,因为 BookService
直接依赖于 MongoClient
。根据官方 Mongo Client 重用准则,应使用单一实例服务生存期在 DI 中注册 MongoClient
。
- 在 Startup.cs 顶部添加以下代码,以解析
BookService
引用 :
using BooksApi.Services;
BookService
类使用以下 MongoDB.Driver
成员对数据库执行 CRUD 操作:
- MongoClient – 读取服务器实例,以执行数据库操作。此类的构造函数提供了 MongoDB 连接字符串:
public BookService(IBookstoreDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
_books = database.GetCollection<Book>(settings.BooksCollectionName);
}
IMongoDatabase – 表示用于执行操作的 Mongo 数据库。本教程在界面上使用泛型 GetCollection
(collection) 方法来获取对特定集合中的数据的访问权限。调用此方法后,对集合执行 CRUD 操作。在GetCollection<TDocument>(collection)
方法调用中:collection
表示集合名称。TDocument
表示存储在集合中的 CLR 对象类型。GetCollection<TDocument>(collection)
返回表示集合的 MongoCollection 对象。在本教程中,对集合调用以下方法:
- DeleteOne – 删除与提供的搜索条件匹配的单个文档。
- Find
– 返回集合中与提供的搜索条件匹配的所有文档。 - InsertOne – 插入提供的对象作为集合中的新文档。
- ReplaceOne – 将与提供的搜索条件匹配的单个文档替换为提供的对象。
添加控制器Add a controller
使用以下代码将 BooksController
类添加到 Controllers 目录:
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(book.Id);
return NoContent();
}
}
}
前面的 Web API 控制器:
- 使用
BookService
类执行 CRUD 操作。 - 包含操作方法以支持 GET、POST、PUT 和 DELETE HTTP 请求。
- 在
Create
操作方法中调用 CreatedAtRoute,以返回 HTTP 201 响应。状态代码 201 是在服务器上创建新资源的 HTTP POST 方法的标准响应。CreatedAtRoute
还会将Location
标头添加到响应中。Location
标头指定新建书籍的 URI。
测试 Web APITest the web API
生成并运行应用。
导航到
http://localhost:<port>/api/books
,测试控制器的无参数Get
操作方法。将显示下面的 JSON 响应:
[
{
"id":"5bfd996f7b8e48dc15ff215d",
"bookName":"Design Patterns",
"price":54.93,
"category":"Computers",
"author":"Ralph Johnson"
},
{
"id":"5bfd996f7b8e48dc15ff215e",
"bookName":"Clean Code",
"price":43.15,
"category":"Computers",
"author":"Robert C. Martin"
}
]
- 导航到
http://localhost:<port>/api/books/{id here}
,测试控制器的重载Get
操作方法。将显示下面的 JSON 响应:
{
"id":"{ID}",
"bookName":"Clean Code",
"price":43.15,
"category":"Computers",
"author":"Robert C. Martin"
}
配置 JSON 序列化选项Configure JSON serialization options
关于在测试 Web API 部分中返回的 JSON 响应,有两个细节需要更改:
- 应更改属性名称的默认驼峰式大小写风格,以匹配 CLR 对象属性名称的 Pascal 大小写。
bookName
属性应作为Name
返回。
为满足上述要求,请进行以下更改:
JSON.NET 已从 ASP.NET 共享框架中删除。将包引用添加到 Microsoft.AspNetCore.Mvc.NewtonsoftJson。
在
Startup.ConfigureServices
中,将以下突出显示的代码链接到AddControllers
方法调用:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<BookstoreDatabaseSettings>(
Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
services.AddSingleton<BookService>();
services.AddControllers()
.AddNewtonsoftJson(options => options.UseMemberCasing());
}
通过上述更改,Web API 的序列化 JSON 响应中的属性名称与 CLR 对象类型中其相应的属性名称匹配。例如,Book
类的 Author
属性序列化为 Author
。
- 在 Models/Book.cs 中,使用以下
[JsonProperty]
特性批注BookName
属性 :
[BsonElement("Name")]
[JsonProperty("Name")]
public string BookName { get; set; }
[JsonProperty]
属性的 Name
值表示 Web API 的序列化 JSON 响应中的属性名称。
- 在 Models/Book.cs 顶部添加以下代码,以解析
[JsonProperty]
属性引用 :
using Newtonsoft.Json;
- 重复测试 Web API 部分中定义的步骤。注意 JSON 属性名称中的区别。
本教程创建对 MongoDB NoSQL 数据库执行创建、读取、更新和删除 (CRUD) 操作的 Web API。
在本教程中,你将了解:
- 配置 MongoDB
- 创建 MongoDB 数据库
- 定义 MongoDB 集合和架构
- 从 Web API 执行 MongoDB CRUD 操作
- 自定义 JSON 序列化
先决条件Prerequisites
- .NET Core SDK 2.2
- Visual Studio 2019 与 ASP.NET 和 Web 开发 工作负载
- MongoDB
配置 MongoDBConfigure MongoDB
如果使用的是 Windows,MongoDB 将默认安装在 C:\Program Files\MongoDB 中。将 C:\Program Files\MongoDB\Server\<version_number>\bin 添加到 Path
环境变量中。通过此更改可以从开发计算机上的任意位置访问 MongoDB。
使用以下步骤中的 mongo Shell 可以创建数据库、创建集合和存储文档。有关 mongo Shell 命令的详细信息,请参阅使用 mongo Shell。
选择开发计算机上用于存储数据的目录。例如,Windows 上的 C:\BooksData 。创建目录(如果不存在)。mongo Shell 不会创建新目录。
打开命令行界面。运行以下命令以连接到默认端口 27017 上的 MongoDB。请记得将
<data_directory_path>
替换为上一步中选择的目录。
mongod --dbpath <data_directory_path>
- 打开另一个命令行界面实例。通过运行以下命令来连接到默认测试数据库:
mongo
- 在命令行界面中运行下面的命令:
use BookstoreDb
如果它不存在,则将创建名为 BookstoreDb 的数据库。如果该数据库存在,则将为事务打开其连接。
- 使用以下命令创建
Books
集合:
db.createCollection('Books')
显示以下结果:
{ "ok" : 1 }
- 使用以下命令定义
Books
集合的架构并插入两个文档:
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'}])
显示以下结果:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5bfd996f7b8e48dc15ff215d"),
ObjectId("5bfd996f7b8e48dc15ff215e")
]
}
备注
本文所示的 ID 与运行此示例时的 ID 不匹配。
- 使用以下命令查看数据库中的文档:
db.Books.find({}).pretty()
显示以下结果:
{
"_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"
}
该架构将为每个文档添加类型 ObjectId
的自动生成的 _id
属性。
数据库可供使用了。你可以开始创建 ASP.NET Core Web API。
创建 ASP.NET Core Web API 项目Create the ASP.NET Core web API project
转到“文件”>“新建”>“项目” 。
选择“ASP.NET Core Web 应用程序”项目类型,然后选择“下一步” 。
将项目命名为“BooksApi”,然后选择“创建” 。
选择“.NET Core” 目标框架和“ASP.NET Core 2.2” 。选择“API”项目模板,然后选择“创建” 。
访问 NuGet 库:MongoDB.Driver 来确定适用于 MongoDB 的 .NET 驱动程序的最新稳定版本。在“包管理器控制台” 窗口中,导航到项目根。运行以下命令以安装适用于 MongoDB 的 .NET 驱动程序:
Install-Package MongoDB.Driver -Version {VERSION}
- 在命令行界面中运行以下命令:
dotnet new webapi -o BooksApi
code BooksApi
将在 Visual Studio Code 中生成并打开以 .NET Core 为目标的新 ASP.NET Core Web API 项目。
状态栏的 OmniSharp 火焰图标变绿后,对话框将询问“'BooksApi' 缺少生成和调试所需的资产。 是否添加它们?”。选择 “是” 。
访问 NuGet 库:MongoDB.Driver 来确定适用于 MongoDB 的 .NET 驱动程序的最新稳定版本。打开“集成终端” 并导航到项目根。运行以下命令以安装适用于 MongoDB 的 .NET 驱动程序:
dotnet add BooksApi.csproj package MongoDB.Driver -v {VERSION}
- 转到“文件”>“新建解决方案”>“.NET Core”>“应用” 。
- 选择“ASP.NET Core Web API”C# 项目模板,然后选择“下一步” 。
- 从“目标框架”下拉列表中选择“.NET Core 2.2”,然后选择“下一步” 。
- 输入“BooksApi”作为“项目名称”,然后选择“创建” 。
- 在“解决方案” 面板中,右键单击项目的“依赖项” 节点,然后选择“添加包” 。
- 在搜索框中输入“MongoDB.Driver”,选择“MongoDB.Driver”包,然后选择“添加包” 。
- 在“许可证接受”对话框中,选择“接受”按钮 。
添加实体模型Add an entity model
将 Models 目录添加到项目根。
使用以下代码将
Book
类添加到 Models 目录:
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; }
}
}
在前面的类中,Id
属性:
- 需要在将公共语言运行时 (CLR) 对象映射到 MongoDB 集合时使用。
- 使用
[BsonId]
进行批注,以将此属性指定为文档的主键。 - 使用
[BsonRepresentation(BsonType.ObjectId)]
进行批注,以允许将参数作为类型string
而非 ObjectId 结构传递。Mongo 处理从string
到ObjectId
的转换。BookName
属性使用[BsonElement]
特性进行批注。Name
的属性值表示 MongoDB 集合中的属性名称。
添加配置模型Add a configuration model
- 向 appsettings.json 添加以下数据库配置值 :
{
"BookstoreDatabaseSettings": {
"BooksCollectionName": "Books",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "BookstoreDb"
},
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
- 使用以下代码将 BookstoreDatabaseSettings.cs 文件添加到 Models 目录 :
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; }
}
}
前面的 BookstoreDatabaseSettings
类用于存储 appsettings.json 文件的 BookstoreDatabaseSettings
属性值 。JSON 和 C# 具有相同的属性名称,目的是简化映射过程。
- 将以下突出显示的代码添加到
Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<BookstoreDatabaseSettings>(
Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
在上述代码中:
- appsettings.json 文件的
BookstoreDatabaseSettings
部分绑定到的配置实例在依赖关系注入 (DI) 容器中注册 。例如,BookstoreDatabaseSettings
对象的ConnectionString
属性使用 appsettings.json 中的BookstoreDatabaseSettings:ConnectionString
属性进行填充 。 IBookstoreDatabaseSettings
接口使用单一实例服务生存期在 DI 中注册。在注入时,接口实例时将解析为BookstoreDatabaseSettings
对象。- 在 Startup.cs 顶部添加以下代码,以解析
BookstoreDatabaseSettings
和IBookstoreDatabaseSettings
引用 :
- 在 Startup.cs 顶部添加以下代码,以解析
using BooksApi.Models;
添加 CRUD 操作服务Add a CRUD operations service
将 Services 目录添加到项目根。
使用以下代码将
BookService
类添加到 Services 目录:
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);
}
}
上面的代码通过构造函数注入从 DI 检索 IBookstoreDatabaseSettings
实例。使用此方法可访问在添加配置模型部分添加的 appsettings.json 配置值 。
- 将以下突出显示的代码添加到
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.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
上面的代码向 DI 注册了 BookService
类,以支持消费类中的构造函数注入。单一实例服务生存期是最合适的,因为 BookService
直接依赖于 MongoClient
。根据官方 Mongo Client 重用准则,应使用单一实例服务生存期在 DI 中注册 MongoClient
。
- 在 Startup.cs 顶部添加以下代码,以解析
BookService
引用 :
using BooksApi.Services;
BookService
类使用以下 MongoDB.Driver
成员对数据库执行 CRUD 操作:
- MongoClient – 读取服务器实例,以执行数据库操作。此类的构造函数提供了 MongoDB 连接字符串:
public BookService(IBookstoreDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
_books = database.GetCollection<Book>(settings.BooksCollectionName);
}
IMongoDatabase – 表示用于执行操作的 Mongo 数据库。本教程在界面上使用泛型 GetCollection
(collection) 方法来获取对特定集合中的数据的访问权限。调用此方法后,对集合执行 CRUD 操作。在GetCollection<TDocument>(collection)
方法调用中:collection
表示集合名称。TDocument
表示存储在集合中的 CLR 对象类型。GetCollection<TDocument>(collection)
返回表示集合的 MongoCollection 对象。在本教程中,对集合调用以下方法:
- DeleteOne – 删除与提供的搜索条件匹配的单个文档。
- Find
– 返回集合中与提供的搜索条件匹配的所有文档。 - InsertOne – 插入提供的对象作为集合中的新文档。
- ReplaceOne – 将与提供的搜索条件匹配的单个文档替换为提供的对象。
添加控制器Add a controller
使用以下代码将 BooksController
类添加到 Controllers 目录:
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(book.Id);
return NoContent();
}
}
}
前面的 Web API 控制器:
- 使用
BookService
类执行 CRUD 操作。 - 包含操作方法以支持 GET、POST、PUT 和 DELETE HTTP 请求。
- 在
Create
操作方法中调用 CreatedAtRoute,以返回 HTTP 201 响应。状态代码 201 是在服务器上创建新资源的 HTTP POST 方法的标准响应。CreatedAtRoute
还会将Location
标头添加到响应中。Location
标头指定新建书籍的 URI。
测试 Web APITest the web API
生成并运行应用。
导航到
http://localhost:<port>/api/books
,测试控制器的无参数Get
操作方法。将显示下面的 JSON 响应:
[
{
"id":"5bfd996f7b8e48dc15ff215d",
"bookName":"Design Patterns",
"price":54.93,
"category":"Computers",
"author":"Ralph Johnson"
},
{
"id":"5bfd996f7b8e48dc15ff215e",
"bookName":"Clean Code",
"price":43.15,
"category":"Computers",
"author":"Robert C. Martin"
}
]
- 导航到
http://localhost:<port>/api/books/{id here}
,测试控制器的重载Get
操作方法。将显示下面的 JSON 响应:
{
"id":"{ID}",
"bookName":"Clean Code",
"price":43.15,
"category":"Computers",
"author":"Robert C. Martin"
}
配置 JSON 序列化选项Configure JSON serialization options
关于在测试 Web API 部分中返回的 JSON 响应,有两个细节需要更改:
- 应更改属性名称的默认驼峰式大小写风格,以匹配 CLR 对象属性名称的 Pascal 大小写。
bookName
属性应作为Name
返回。
为满足上述要求,请进行以下更改:
- 在
Startup.ConfigureServices
中,将以下突出显示的代码链接到AddMvc
方法调用:
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.AddMvc()
.AddJsonOptions(options => options.UseMemberCasing())
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
通过上述更改,Web API 的序列化 JSON 响应中的属性名称与 CLR 对象类型中其相应的属性名称匹配。例如,Book
类的 Author
属性序列化为 Author
。
- 在 Models/Book.cs 中,使用以下
[JsonProperty]
特性批注BookName
属性 :
[BsonElement("Name")]
[JsonProperty("Name")]
public string BookName { get; set; }
[JsonProperty]
属性的 Name
值表示 Web API 的序列化 JSON 响应中的属性名称。
- 在 Models/Book.cs 顶部添加以下代码,以解析
[JsonProperty]
属性引用 :
using Newtonsoft.Json;
- 重复测试 Web API 部分中定义的步骤。注意 JSON 属性名称中的区别。
向 Web API 添加身份验证支持Add authentication support to a web API
ASP.NET Core 标识将用户界面 (UI) 登录功能添加到 ASP.NET Core Web 应用。若要保护 Web API 和 SPA,请使用以下项之一:
- Azure Active Directory
- Azure Active Directory B2C (Azure AD B2C)]
- IdentityServer4
IdentityServer4 是适用于 ASP.NET Core 3.0 的 OpenID Connect 和 OAuth 2.0 框架。IdentityServer4 支持以下安全功能:
- 身份验证即服务 (AaaS)
- 跨多个应用程序类型的单一登录/注销 (SSO)
- API 的访问控制
- Federation Gateway
有关详细信息,请参阅欢迎使用 IdentityServer4。
后续步骤Next steps
有关构建 ASP.NET Core Web API 的详细信息,请参阅以下资源: