使用 ASP.NET Core 和 MongoDB 创建 Web API

07-11 1727阅读

先决条件

Visual Studio:

使用 ASP.NET Core 和 MongoDB 创建 Web API
(图片来源网络,侵删)
  • .NET Core SDK 3.0 或更高版本
  • Visual Studio 2019 与 ASP.NET 和 Web 开发工作负载
  • MongoDB

    配置 MongoDB

    如果使用的是 Windows,MongoDB 将默认安装在 C:\Program Files\MongoDB 中。 将 C:\Program Files\MongoDB\Server\version_number>\bin 添加到 Path 环境变量。 通过此更改可以从开发计算机上的任意位置访问 MongoDB。

    使用以下步骤中的 mongo Shell 可以创建数据库、创建集合和存储文档。

    1. 选择开发计算机上用于存储数据的目录。 例如,在 Windows 上为 C:\BooksData。 创建目录(如果不存在)。 mongo Shell 不会创建新目录。

    2. 打开命令行界面。 运行以下命令以连接到默认端口 27017 上的 MongoDB。 请记得将  替换为上一步中选择的目录。

      mongod --dbpath 
      
    3. 打开另一个命令行界面实例。 通过运行以下命令来连接到默认测试数据库:

      mongo
      
    4. 在命令行界面中运行以下命令:

      use BookstoreDb
      

      如果它不存在,则将创建名为“BookstoreDb”的数据库。 如果该数据库存在,则将为事务打开其连接。

    5. 使用以下命令创建 Books 集合:

      db.createCollection('Books')
      

      显示以下结果:

      { "ok" : 1 }
      
    6. 使用以下命令定义 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 不匹配。

    7. 使用以下命令查看数据库中的文档:

      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 项目​​​​​​​​​​​​​​

    1. 转到“文件”“新建”“项目”。

    2. 选择“ASP.NET Core Web 应用程序”项目类型,然后选择“下一步” 。

    3. 将项目命名为“BooksApi”,然后选择“创建”。

    4. 选择“.NET Core”目标框架和“ASP.NET Core 3.0”。 选择“API”项目模板,然后选择“创建” 。

    5. 访问 NuGet 库:MongoDB.Driver 来确定适用于 MongoDB 的 .NET 驱动程序的最新稳定版本。 在“包管理器控制台”窗口中,导航到项目根。 运行以下命令以安装适用于 MongoDB 的 .NET 驱动程序:

      PowerShell复制

      Install-Package MongoDB.Driver -Version {VERSION}
      

    添加实体模型

    1. 将 Models 目录添加到项目根。

    2. 使用以下代码将 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 而非 [BsonRepresentation(BsonType.ObjectId)] 结构传递。 Mongo 处理从 string 到 ObjectId 的转换。

      BookName 属性使用 [BsonElement] 特性进行批注。 Name 的属性值表示 MongoDB 集合中的属性名称。

    添加配置模型

    1. 向 appsettings.json 添加以下数据库配置值:

      {
        "BookstoreDatabaseSettings": {
          "BooksCollectionName": "Books",
          "ConnectionString": "mongodb://localhost:27017",
          "DatabaseName": "BookstoreDb"
        },
        "Logging": {
          "IncludeScopes": false,
          "Debug": {
            "LogLevel": {
              "Default": "Warning"
            }
          },
          "Console": {
            "LogLevel": {
              "Default": "Warning"
            }
          }
        }
      }
      
    2. 使用以下代码将 BookstoreDatabaseSettings.cs 文件添加到 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# 具有相同的属性名称,目的是简化映射过程。

    3. 将以下突出显示的代码添加到 Startup.ConfigureServices:

      public void ConfigureServices(IServiceCollection services)
      {
          // requires using Microsoft.Extensions.Options
          services.Configure(
              Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
          services.AddSingleton(sp =>
              sp.GetRequiredService().Value);
          services.AddControllers();
      }
      

      在上述代码中:

      • appsettings.json 文件的 BookstoreDatabaseSettings 部分绑定到的配置实例在依赖关系注入 (DI) 容器中注册。 例如,BookstoreDatabaseSettings 对象的 ConnectionString 属性使用 appsettings.json 中的 BookstoreDatabaseSettings:ConnectionString 属性进行填充。
      • IBookstoreDatabaseSettings 接口使用单一实例IBookstoreDatabaseSettings在 DI 中注册。 在注入时,接口实例时将解析为 BookstoreDatabaseSettings 对象。
    4. 将以下代码添加到 Startup.cs 的顶部以解析 BookstoreDatabaseSettings 和 IBookstoreDatabaseSettings 引用:

      using BooksApi.Models;
      

    添加 CRUD 操作服务

    1. 将 Services 目录添加到项目根。

    2. 使用以下代码将 BookService 类添加到 Services 目录:

      using BooksApi.Models;
      using MongoDB.Driver;
      using System.Collections.Generic;
      using System.Linq;
      namespace BooksApi.Services
      {
          public class BookService
          {
              private readonly IMongoCollection _books;
              public BookService(IBookstoreDatabaseSettings settings)
              {
                  var client = new MongoClient(settings.ConnectionString);
                  var database = client.GetDatabase(settings.DatabaseName);
                  _books = database.GetCollection(settings.BooksCollectionName);
              }
              public List Get() =>
                  _books.Find(book => true).ToList();
              public Book Get(string id) =>
                  _books.Find(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 实例。 使用此方法可访问在添加配置模型部分中添加的 配置值。

    3. 将以下突出显示的代码添加到 Startup.ConfigureServices:

      public void ConfigureServices(IServiceCollection services)
      {
          services.Configure(
              Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
          services.AddSingleton(sp =>
              sp.GetRequiredService().Value);
          services.AddSingleton();
          services.AddControllers();
      }
      

      上面的代码向 DI 注册了 BookService 类,以支持消费类中的构造函数注入。 单一实例服务生存期是最合适的,因为 BookService 直接依赖于 MongoClient。 根据官方 Mongo Client 重用准则,应使用单一实例服务生存期在 DI 中注册 MongoClient。

    4. 将以下代码添加到 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(settings.BooksCollectionName);
      }
      
    • IMongoDatabase:表示用于运行操作的 Mongo 数据库。 本教程在界面上使用泛型 (collection)">GetCollection(collection) 方法来获取对特定集合中数据的访问权限。 调用此方法后,对集合运行 CRUD 操作。 在 GetCollection(collection) 方法调用中:

      • collection 表示集合名称。
      • TDocument 表示存储在集合中的 CLR 对象类型。

      GetCollection(collection) 返回表示集合的 GetCollection(collection) 对象。 在本教程中,对集合调用以下方法:

      • DeleteOne:删除与提供的搜索条件匹配的单个文档。
      • ">Find:返回集合中与提供的搜索条件匹配的所有文档。
      • InsertOne:插入提供的对象作为集合中的新文档。
      • ReplaceOne:将与提供的搜索条件匹配的单个文档替换为提供的对象。

        添加控制器

        使用以下代码将 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 Get() =>
                    _bookService.Get();
                [HttpGet("{id:length(24)}", Name = "GetBook")]
                public ActionResult Get(string id)
                {
                    var book = _bookService.Get(id);
                    if (book == null)
                    {
                        return NotFound();
                    }
                    return book;
                }
                [HttpPost]
                public ActionResult 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();
                }
            }
        }
        

        前面的 Web API 控制器:

        • 使用 BookService 类运行 CRUD 操作。
        • 包含操作方法以支持 GET、POST、PUT 和 DELETE HTTP 请求。
        • 在 Create 操作方法中调用 CreatedAtRoute,以返回 CreatedAtRoute 响应。 状态代码 201 是在服务器上创建新资源的 HTTP POST 方法的标准响应。 CreatedAtRoute 还会将 Location 标头添加到响应中。 Location 标头指定新建书籍的 URI。

          测试 Web API

          1. 生成并运行应用。

          2. 导航到 https://localhost:/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"
              }
            ]
            
          3. 导航到 https://localhost:/api/books/{id here},测试控制器的重载 Get 操作方法。 将显示下面的 JSON 响应:

            {
              "id":"{ID}",
              "bookName":"Clean Code",
              "price":43.15,
              "category":"Computers",
              "author":"Robert C. Martin"
            }
            

          配置 JSON 序列化选项

          关于在测试 Web API 部分中返回的 JSON 响应,有两个细节需要更改:

          • 应更改属性名称的默认驼峰式大小写风格,以匹配 CLR 对象属性名称的 Pascal 大小写。
          • bookName 属性应作为 Name 返回。

            为满足上述要求,请进行以下更改:

            1. Json.NET 已从 ASP.NET 共享框架中删除。 将包引用添加到 Microsoft.AspNetCore.Mvc.NewtonsoftJson。

            2. 在 Startup.ConfigureServices 中,将以下突出显示的代码链接到 AddControllers 方法调用:

              public void ConfigureServices(IServiceCollection services)
              {
                  services.Configure(
                      Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
                  services.AddSingleton(sp =>
                      sp.GetRequiredService().Value);
                  services.AddSingleton();
                  services.AddControllers()
                      .AddNewtonsoftJson(options => options.UseMemberCasing());
              }
              

              通过上述更改,Web API 的序列化 JSON 响应中的属性名称与 CLR 对象类型中其相应的属性名称匹配。 例如,Book 类的 Author 属性序列化为 Author。

            3. 在 Models/Book.cs 中,使用以下 [JsonProperty] 特性批注 BookName 属性:

              [BsonElement("Name")]
              [JsonProperty("Name")]
              public string BookName { get; set; }
              

              [JsonProperty] 属性的 Name 值表示 Web API 的序列化 JSON 响应中的属性名称。

            4. 将以下代码添加到 Models/Book.cs 的顶部以解析 [JsonProperty] 特性引用:

              using Newtonsoft.Json;
              
            5. 重复测试 Web API 部分中定义的步骤。 注意 JSON 属性名称中的区别。

            向 Web API 添加身份验证支持

            ASP.NET Core Identity 将用户界面 (UI) 登录功能添加到 ASP.NET Core Web 应用。 若要保护 Web API 和 SPA,请使用以下项之一:

            • Microsoft Entra ID
            • Azure Active Directory B2C (Azure AD B2C)
            • Duende IdentityServer。 Duende IdentityServer 是第三方产品。
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]