65.9K
CodeProject 正在变化。 阅读更多。
Home

Web API - 添加 Swagger、SQL Server、日志记录、CORS、导出到 Excel 和 Docker

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (31投票s)

2019年9月9日

CPOL

18分钟阅读

viewsIcon

94923

downloadIcon

2642

一份备忘单,用于尽可能快速、轻松地启动和运行您的 Web API

引言

自 2016 年发布以来,ASP.NET Core 取得了惊人的进步,并且每一版都似乎越来越好、越来越友好、对开发者也越来越友好。

Web API 比旧的 WCF 服务(我们还是别提 SOAP 了……)有了巨大的改进,并且有很多“入门”资源。这篇文章不是为了重新发明轮子,而是一个“备忘单”,列出了您需要执行的步骤,以完成以下操作:

  1. 创建新的 Web API 项目
  2. 将 Swagger 添加到您的项目中
  3. 将您的项目连接到 SQL Server 数据库
  4. 向您的项目添加日志记录,以便任何异常或日志消息都可以保存在 SQL Server 表中(而不是被转储到 IIS 的某个 *.txt 日志文件中)
  5. 向您的项目添加 CRUDE。没错,这不是一个拼写错误。我们将实现标准的“创建-读取-更新-删除”功能,并且……为了展示有多么容易……导出。我们将添加一个端点,使用 Open XML 库将数据导出到真正的 .xlsx 文件,纯粹为了好玩。
  6. 将 Web API 部署到 Azure 作为 Docker 映像,然后同时在本地和 Azure 容器中运行该映像。

这四个步骤是我每次创建 Web API 时都会遵循的,所以我认为最好尽可能快速、无痛地记录下来,以便我们有更多时间专注于完成真正的工作!

现在,我确实提供了一个包含本文示例代码的 MikesBank.zip 文件,但我强烈建议您**不要**使用它。

Visual Studio 2019 和 ASP.NET Core 几乎每个月都在变化……所以,最好从头开始创建您自己的项目,并按照这些说明进行操作,使用您在阅读本文时微软提供的任何新模板,而不是使用我提供的示例,因为它很可能在您读完这一段时就已经过时了一半。

祝您阅读愉快!

要求

要学习本文,您将需要

  • C# 知识
  • Visual Studio 2019 的副本
  • 已安装 .NET Core v3 SDK(或更高版本)
  • SQL Server Management Studio(或者您可以修改连接字符串,指向您自己的数据库类型)

我建议您在遵循这些说明之前**更新**您的 VS2019 和 .NET Core。

如果您使用的是 Visual Studio 2017 或 .NET Core 2.x,那么您需要确保导入与您的版本兼容的“nuget”包。这是 Visual Studio 的“nuget 包管理器”不适合开发者的地方之一,因为它会很乐意让您出错。

1. 创建新的 Web API 项目

这已经被讨论过很多次了,我相信大家都知道如何做。

在 Visual Studio 2019 中

  1. 点击 **文件** \ **新建** \ **项目**……
  2. 在第一个屏幕上,选择 **ASP.NET Core Web 应用程序**,然后点击 **下一步**。
  3. 在第二个屏幕上,我们将项目名称输入为 **MikesBank**,然后点击 **创建**。
  4. 在第三个屏幕上,确保“ASP.NET Core”的版本是 3.x,选择 **API**,然后点击 **创建**。
  5. 请注意,Visual Studio 2019 默认不再询问您是否要创建新的 git 存储库。但是,在 VS2019 窗口的右下角,有一个**添加到源代码管理**按钮,您可以点击它。如果选择此选项,然后选择 **Git**,您现在可以让 VS2019 将您的源代码推送到 Azure 中一个 DevOps 友好的项目中。这是添加持续集成、管道、工作项板的绝佳起点,非常棒。它太棒了……

所以…… Visual Studio 将为您创建一个基本的 API 项目,该项目返回一些硬编码的数据。

如果您在 Chrome 中运行该项目,您将看到一些 JSON 数据。太棒了!

但是,如果您仍然使用 Internet Explorer,情况会变得奇怪。它不会打开网页,而是会打开**下载视图**窗口,询问您是想打开还是保存 weatherforecast.json。这有点令人困惑,特别是如果您习惯了上一版本的 API 模板。

在接下来的步骤中,我们将改进这个第一印象……

2. 将 Swagger 添加到项目中

考虑到 Visual Studio 的开发者友好性,我总是很惊讶,当我们告诉它我们正在创建一个 Web API 项目时,**为我的 API 创建一个 Swagger 页面**并不是一个选项。不过,添加它也很容易。

要将 Swagger 添加到您的项目中

  1. 右键单击您的项目名称,然后选择 **管理 NuGet 包……**
  2. 点击 **浏览** 选项卡,然后搜索并安装 `swashbuckle.aspnetcore`
  3. 现在您可以关闭这个 **nuget 包管理器**屏幕。
  4. 我们现在需要对 `startup.cs` 文件进行一些更改。首先,在 `Configure()` 函数中添加这些行
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json","MikesBank API");
        c.RoutePrefix = string.Empty;
    });
  5. 请注意 `RoutePrefix` 行……这将使 Swagger 页面成为我们的默认页面。因此,当我调试时,Swagger 页面将出现,当 URL 指向根路径时,例如:
    https://:44350/
  6. 接下来,我将稍微修改构造函数,并添加一个新的 `env` 变量
            public Startup(IHostEnvironment env, IConfiguration configuration)
            {
                Configuration = configuration;
                this.env = env;
            }
            private IHostEnvironment env { get; }

    有了这些,我们就可以对 `ConfigureServices()` 函数进行更改了

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    
        services.AddMvc();
    
        var pathIncludeXmlComments = $@"{env.ContentRootPath}\{env.ApplicationName}.xml";
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "MikesBank API", Version = "v1" });
    
             if (System.IO.File.Exists(pathIncludeXmlComments))
                c.IncludeXmlComments(pathIncludeXmlComments);
        });
    }

    您还需要在此文件顶部添加一个额外的 `using` 语句

    using Microsoft.OpenApi.Models;
  7. 代码更改已完成,但现在,我们只需要对项目设置进行一些更改。再次右键单击您的项目名称,然后选择 **属性**。然后,选择 **生成** 选项卡。
  8. 在 **错误和警告** 部分,将 `;1591` 添加到要忽略的警告列表中。如果我们选择在 Web API 控制器中添加注释,那太好了!但我不想在尚未添加注释时让 Visual Studio 划线。这本身并不是一个 bug/警告,所以我忽略了这个警告,以忽略此类警告。
    1701;1702;1591
  9. 仍在同一屏幕上,在 **输出** 部分,勾选 **XML 文档文件**

  10. 现在,切换到 **调试** 选项卡,并从 **启动浏览器** 文本框中删除 `weatherforecast`,使其变为空白。

如果您现在运行该项目,您将看到 Swagger 网站,其中列出了 VS2019 为我们创建的示例端点。

看起来不错!如果您想运行简单的**获取所有值**函数,可以点击第一个 `GET` 行,点击**试用**按钮,然后点击**执行**按钮,您将在响应正文中看到天气预报值,就像以前一样。

好的,它不像 Postman 或 Fiddler 那么复杂,但它是免费的、友好的,并且非常有用。

让 Swagger 在此页面上包含注释也非常简单,只需在端点上方附加一个 `summary` 或 `remarks` 部分。例如,我们可以进入 `WeatherForecastController.cs` 文件,并在 Get 端点上方添加一些注释

 /// <summary>
 /// This is the Summary, describing the endpoint
 /// </summary>
 /// <remarks>
 /// These are the Remarks for the WeatherForecast endpoint
 /// </remarks>
 [HttpGet]
 public IEnumerable<WeatherForecast> Get()
 {
     ... etc...

请记住,Swagger 本身**确实**会定期更新,并且(再次)到您阅读本文时,或者当您在谷歌搜索 Swagger 代码无法生成/显示的问题时,请务必查看最新文档。

3. 将您的项目连接到 SQL Server 数据库

好的,现在我们将 Web API 连接到 SQL Server 数据库。为此,请再次进入 **nuget 包管理器**,搜索并安装 `Microsoft.EntityFrameworkCore.SqlServer` 包。

现在,我更喜欢使用**数据库优先**的方法,即我有一个已经“活生生”的数据库,然后将其链接到我的 Web API。在本篇文章中,我在我的 localhost 服务器上创建了一个名为 `Southwind` 的 SQL Server 数据库,其中包含五个表:`Location`、`Department`、`Employee`、`JobRole` 和 `Logging`。

如果您想跟着做,我提供了一个 `Southwind.sql` 脚本,它将为您创建数据库、表和数据。

现在,让我们告诉我们的 WebAPI 关于这个数据库。首先,我们需要打开 `appsettings.json` 文件,并为它添加一个连接字符串

  "ConnectionStrings": {
    "SouthwindDatabase": "Server=.;Database=Southwind;Trusted_Connection=True;"
  },

现在,打开 `startup.cs`,并在 `ConfigureServices()` 函数中添加此项

var ConnectionString = Configuration.GetConnectionString("SouthwindDatabase");
services.AddDbContext<SouthwindContext>(options =>
    options.UseSqlServer(ConnectionString)
);

我们还需要在 `startup.cs` 的顶部添加两个 `using` 语句,以确保我们没有破坏编译

using Microsoft.EntityFrameworkCore;
using MikesBank.Models;

我们还可以删除 `Controllers` 文件夹中的 `WeatherForecastController.cs` 文件。

接下来,我们需要为我们感兴趣的每个数据库表创建一个 `class`,以及一个 `DbContext` 类来将它们全部集中在一起。有两种方法可以做到这一点。

3.1 让 VS2019 为您创建代码

我们可以让 Visual Studio 为我们创建这些,它将根据我们数据库中表的结构创建类。

为此,请打开程序包管理器控制台(点击 **工具 \ Nuget 包管理器 \ 程序包管理器控制台**),然后输入以下命令,将我的连接字符串替换为您自己数据库的连接字符串

Scaffold-DbContext "Server=localhost;Database=Southwind;Trusted_Connection=True;" 
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

这将神奇地为我们创建一个 `SouthwindContext` 类,以及五个类,每个类对应一个数据库表。

如果您只想为**部分**数据库表创建一个 `class`,可以使用 `-Tables` 参数,然后列出表名。

Scaffold-DbContext "Server=localhost;Database=Southwind;Trusted_Connection=True;" 
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models 
-Tables "Employee","JobRole","Department"

请注意,`Scaffold-DbContext` 命令**不起作用**,前提是您的代码在运行它之前没有成功生成。所以,在运行此命令**之前**,请检查您的代码是否成功生成。

您可以在 此处查看其他脚手架命令选项。

3.2 手动创建代码

或者,您可以手动创建数据库表的类。让我们看看如何为我们的 `Employee` 表做到这一点。

首先,在您的项目中创建一个名为 `Models` 的文件夹。在此文件夹中,在名为 `Employee.cs` 的文件中创建一个新的 `class`

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;

namespace MikesBank.Models
{
    [Table("Employee")]
    public class Employee
    {
        [Key]
        [JsonPropertyName("id")]
        public int Employ_ID { get; set; }

        public int? Dept_ID { get; set; }
        public int? JobRol_ID { get; set; }

        [JsonPropertyName("firstName")]
        public string Employ_First_Name { get; set; }

        [JsonPropertyName("lastName")]
        public string Employ_Last_Name { get; set; }

        [JsonPropertyName("imageURL")]
        public string Employ_Image_URL { get; set; }

        [JsonPropertyName("dob")]
        public DateTime? Employ_DOB { get; set; }
        
        //  ... etc .... 
    }
}

现在,我的测试数据库实际上是由一位数据库架构师创建的,他决定为大多数数据库字段添加一个前缀(例如 `Employ_ID`、`Employ_First_Name` 等)。这在编写 SQL 命令时非常有用,但会让 C# 变得混乱。使用这些 `JsonPropertyName` 属性,我们可以轻松定义我们希望 JSON 字段如何序列化,例如:

[
  {
    "id": 3000,
    "dept_ID": 1000,
    "jobRol_ID": 1001,
    "firstName": "Michael",
    "lastName": "Gledhill",
    "imageURL": "",
    "dob": "1980-12-25T00:00:00"
  },

同样在此 `Models` 文件夹中,让我们创建一个名为 `MikesBankContext.cs` 的文件,该文件将描述我们数据库中的各种表

using Microsoft.EntityFrameworkCore;

namespace MikesBank.Models
{
    public class MikesBankContext : DbContext
    {
        public MikesBankContext(DbContextOptions<MikesBankContext> options)
            : base(options)
        {
        }

        public DbSet<Employee> Employees { get; set; }
    }
}

现在我们拥有了将数据库 CRUD 操作添加到 Web API 的所有构建块。

3.3 添加一个控制器

因此,使用这两种方法之一,我们现在有了一个 `DbContext` 类,以及一个对应于我们感兴趣的每个数据库表的 `class`。

接下来,我们将为我们的一个类添加一个控制器,该控制器将为该类创建 `GET`、`PUT`、`POST` 和 `DELETE` WebAPI 端点。让我们用我们的 `Employee` 类来做这件事。

只需右键单击 `Controllers` 文件夹,选择 **添加 \ 控制器**,选择最后一个选项 **带操作的 API 控制器,使用 Entity Framework**,然后点击 **添加**。

VS2019 然后会为我们的一個表创建一个 CRUD 端点集。如果您现在运行该项目,您将看到我们的 `Employees` 端点集合

3.4 为 Swagger 页面添加注释

开发人员喜欢记录。是的。

我们可以轻松地将注释添加到此屏幕,只需进入一个控制器文件(例如 `EmployeeController.cs`),然后修改注释。

只需删除现有注释,然后将光标放在 `[HttpGet]` 上方的空行上,键入 `///`,Visual Studio 将为您提供输入注释的占位符。

/// <summary>
/// Load a list of all employee records from the database
/// </summary>
/// <returns>
/// An enumerable list of Employee records
/// </returns>
[HttpGet]
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
{
  return await _context.Employee.ToListAsync();
}

这就是我们让 Web API 连接到 SQL Server 数据库并读写数据的方式。我很想为此承担功劳,但正如您所见,Visual Studio 完成了(几乎)所有工作。

我们只需要记住要采取的步骤。

4. 记录到 SQL Server

现在,我非常不喜欢发生错误/异常时,错误字符串仅仅转储到 IIS 服务器上某个随机的 .txt 文件中。将消息发送到 SQL Server 上的 `Logging` 表会更有用,这样我们就可以跟踪这些问题,也许在我们的管理员的**日志查看器**屏幕上列出它们,保存堆栈跟踪等等。

当然,有一个陷阱:如果异常是由于我们无法连接到数据库而抛出的,那么……好吧……异常消息肯定不会存储在数据库中,因为它找不到它!

当然,我们可以寻求第三方帮助,例如 `nLog`,来处理我们的日志记录,但个人而言,我更喜欢自己动手。

首先,正如您所见,我在 SQL Server 数据库中有一个 `Logging` 表。

这个表并不复杂。`Log_Severity`、(异常)`Log_Message` 和 `Log_StackTrace` 字段都将来自刚刚发生的任何异常,并且我有一个 `Log_Source` 字段,我们可以填充它来说明应用程序的哪个区域抛出了异常。

哦,我的 `Update_Time` 字段(我在我的每个表中都有一个)**总是**包含 UTC `timezone` 的日期时间。我们可能有来自不同国家的用户,他们希望知道异常何时发生,以他们当地的时间为准。

要使用此(或其他)表结构在我们的代码中,我们需要这样做。

  1. 在我们的项目中创建一个名为“LogProvider”的新文件夹。
  2. 我提供了一个 `LogProvider.zip` 文件,将此 .zip 文件中的 4 个文件解压到此文件夹中。
  3. 在这些文件的每一个文件中,命名空间当前设置为 `MikesBank.LogProvider`。您需要将其更改为您自己的命名空间(取决于您为项目命名的名称)。
  4. 在 `SqlHelper.cs` 和 `DBLogger.cs` 文件中,有特定于我的日志记录数据库表的代码。如果您的表名称或字段不同,您需要更改此代码。
  5. 在 `Startup.cs` 中,添加行 `using MikesBank.LogProvider;`
  6. 在 `Configure()` 函数中,我们需要注入一个额外的依赖项
public void Configure(IApplicationBuilder app,
                     IHostingEnvironment env, ILoggerFactory loggerFactory)

我们现在可以在 `Configure()` 函数中添加以下行

loggerFactory.AddConsole(Configuration.GetSection("Logging"));
//  The following "AddContext" comes from our DBLoggerExtensions class.
//  We will log any errors of Information of higher.
//  (Trace=0, Debug=1, Information=2, Warning=3, Error=4, Critical=5, None=6)
loggerFactory.AddContext(LogLevel.Information,
             Configuration.GetConnectionString("SouthwindDatabase"));

此时,如果您尝试生成项目,可能会收到一个错误,提示 `ILoggerFactory` 不包含 `AddContext` 的定义。要解决此问题,我们需要告诉它我们的扩展方法在哪里。在 `Startup.cs` 的顶部,添加此行

using MikesBank.LogProvider;

现在,让我们试试看。

在 `EmployeesController.cs` 中,我现在可以添加日志记录。为此,我需要添加一个新的变量

private readonly ILogger logger;

……以及一个新的 `using` 语句……

using Microsoft.Extensions.Logging;

然后,我可以修改构造函数

public EmployeesController(SouthwindContext context, ILoggerFactory loggerFactory)
{
    _context = context;
    logger = loggerFactory.CreateLogger<EmployeesController>();
}

就是这样!

您现在可以愉快地在其中插入任意多的 `LogInformation`、`LogWarning` 或 `LogErrors`。例如:

[HttpGet]
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
{
    logger.LogInformation("Loading a list of Employee records");
    return await _context.Employee.ToListAsync();
}

只是有一个恼人的问题。在运行此代码并调用 `GET` 端点后,我**确实**在我的 `Logging` 表中收到了**加载 Employee 记录列表**的消息,但我也收到了大量来自后台的消息。就我个人而言,我觉得这些消息使得查找我真正关心的**Log**消息变得非常困难,我宁愿将它们关闭。

要做到这一点,您可以进入 `appsettings.Development.json` 文件,并修改将包含哪些类型的日志消息来自 Microsoft 和 System 库。如果将其更改为**警告**,那么您的日志就不会填满所有这些额外的 Entity Framework 消息。

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Warning",
      "Microsoft": "Warning"
    }
  }
}

显然,这是可选的,也许您会在开发构建中看到如此详细的信息。这取决于您。

还有最后一件事。

我最恼火的一些 API 的问题之一就是可怕的“HTTP 响应 500:服务器内部错误”。当您自己的 API 抛出此异常时,通常是因为出了问题,并且您的代码没有捕捉到问题,或者没有优雅地处理它。

当然,由于您没有捕捉到异常,所以您肯定不会尝试将其发送到日志,以便您的开发人员和支持团队可以调查原因。所以,**请**将您的每个端点包装在一个 `try...catch` 中,并确保任何异常消息都最终进入您的 `Logging` 表。

这样做非常容易,但将为您节省很多日后的烦恼。

public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
{
    try
    {
        logger.LogInformation("Loading a list of Employee records");
        return await _context.Employee.ToListAsync();
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "An exception occurred in the GetEmployee() endpoint");
        return new BadRequestObjectResult(ex.Message);
    }
}

显然,在生产版本中,您可能不想返回完整的异常消息(如上),您可以根据需要进行修改。

5. 启用 CORS

如果您正在开发软件,那么很可能您希望您的 Angular/JavaScript 应用程序在它们仍然托管在 `localhost` 上时调用您的 Web API 端点。不幸的是,CORS 会阻止这一点,并会给您带来很多错误。

现在,有很多指南显示如何正确设置 CORS,但如果您只是想在开发过程中**消除所有控制器上的**这些错误,请这样做:

  • 添加 `Microsoft.AspNetCore.Cors` nuget 包。
  • 在 `Startup.cs` 中,进入 `ConfigureServices()` 方法并添加此行
    services.AddCors();
  • 同样在 `Startup.cs` 中,进入 `Configure()` 方法并添加此行
    app.UseCors(builder => 
        builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()
    );

同样,这是一个快捷方式,纯粹是为了在**开发期间**消除这些 CORS 错误。部署到实时应用程序时,您将需要创建自己的策略,并且可能只将其应用于某些控制器或端点。

但这两种更改至少可以防止您在开发过程中被阻止。

6. 添加“导出到 Excel”

是的,我知道……很可能我们中的没有人会添加一个 Web API 端点来返回一个原始 Excel 文件,其中包含您表中所有数据。但是,我们已经走到了这一步,并且因为它非常简单,所以让我们来看看我们将如何做到这一点。即使如此,它也对您其他的 ASP.NET Core 项目很有用。

首先,我们需要最后一次进入**NuGet 包管理器**,并安装 `DocumentFormat.OpenXml` 包。这使我们能够创建 Excel 文件(`*.xlsx`),即使我们的服务器上没有安装 Excel。

接下来,在您的项目中创建一个名为 `Helpers` 的文件夹,并将附加的 `CreateExcelFile.cs` 保存到此文件夹中。

这个 C# 库是我在 2014 年编写的**导出到 Excel** 库,您可以在 我的 CodeProject 文章中了解更多信息。

有了这个文件,我们就可以开始了。

向我们的控制器添加导出端点就像加载我们的数据,然后调用 `StreamExcelDocument` 函数,将要导出的数据和要使用的文件名传递给它一样简单

[HttpGet("ExportToExcel")]
public async Task<IActionResult> ExportEmployeesToExcel()
{
    try
    {
        List<Employee> employees = await _context.Employee.ToListAsync();
        FileStreamResult fr = ExportToExcel.CreateExcelFile.StreamExcelDocument
                             (employees, "Employees.xlsx");
        return fr;
    }
    catch (Exception ex)
    {
        return new BadRequestObjectResult(ex);
    }
}

有多简单!!

作为一名在金融行业工作过的人,让我告诉您,拥有一个简单、可重用的**导出到 Excel** 函数是**无价的**。这是我的客户每次都会要求的功能……他们热爱 Excel!

7. 支持 Docker

当我开始研究 Docker 支持时,我真的认为这会很简单。毕竟,当您在 Visual Studio 2017 或 2019 中创建项目时,它会询问您是否需要 Docker 支持。从那里开始,很容易使用**发布**将应用程序作为 Docker 映像发布到 Azure。所以这一定很简单。

事实并非如此。

首先,当您创建项目并表示您**确实**想要 Docker 支持时,您很可能会选择 Windows(而不是 Linux)。这会为您创建一个名为 `Dockerfile` 的文件,但(在撰写本文时)它提供的 .NET Core 版本在 Azure 中**不受支持**。因此,当您发布到 Azure 时,您将在 Azure 门户中看到您的应用程序列表作为新的**容器注册表**……但 Azure 将无法运行它。

实际上有一个选项可以*运行此注册表的实例*,但实际找到此选项并不那么清楚。

更糟糕的是,如果出现问题,错误消息几乎毫无用处。

这到底是什么意思?

要找出错误的原因,您需要点击 Azure 窗口右上角的 **>** 按钮,并运行以下命令

az group deployment operation list
--resource-group <YourResourceGroup> --name Microsoft.ContainerInstance

这将显示一个长长的 JSON 消息,其中包含错误

(我将这个冗长的错误消息 PPhotoshop 成两行,以便您轻松阅读。)

啊,好的。所以,Visual Studio 为我们创建了一个容器注册表,但使用了它实际不支持的 Windows 版本。我相信这方面的可用性可以得到改进……

此问题的原因似乎是 Visual Studio 为我们创建的 Dockerfile 文件。它提到了比 Azure 支持的 .NET Core SDK 和运行时版本更高的版本。

我们可以通过将前几行更改为

FROM mcr.microsoft.com/dotnet/core/runtime:2.2-nanoserver-sac2016 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-nanoserver-sac2016 AS build
WORKDIR /src
COPY ["MikesBank/MikesBank.csproj", "MikesBank/"]
... etc ...

进行此更改后,您可以重新发布到 Azure,并运行这个新的容器注册表的一个实例。

在本地运行 Docker 映像

我们还可以将 Docker 注册表运行在我们自己的 Windows 本地副本上。为此,请确保您已安装 **Docker For Windows** 和 **Azure CLI**,然后按照以下步骤操作

  1. 告诉 Azure CLI 您的容器注册表所在的订阅的 GUID。
  2. 登录到订阅。
  3. 登录到 Azure 容器注册表。
  4. 使用 Docker **pull** 命令将映像的副本下载到您的笔记本电脑/服务器。
  5. 运行此映像的本地副本。
  6. 获取所有正在运行的容器的列表,以获得我们新容器的 ID。
  7. 运行 Docker **inspect** 命令以查找您需要在浏览器中打开才能访问应用程序的 IP 地址。

因此,总的来说,命令看起来像下面的内容(显然,您需要指定 Azure 为您的注册表副本创建的名称)

az account set --subscription <subscription_id>

az login

az acr login --name MikesBank20190925022604

docker pull mikesbank20190925022604.azurecr.io/mikesbank:latest

docker run mikesbank:latest

docker image ls

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" <container_id>

呼!经过所有这些之后,您将获得可以在浏览器中打开的 IP 地址,并看到 Swagger 页面。不错!

摘要

就是这样!

我们现在有了一个不错的 ASP.NET Core Web API 项目,具有友好的 Swagger 页面、SQL Server 连接和日志记录。另外,如果您**真的**想在下一次工作面试中给人留下深刻印象,并且能够告诉他们您的 API 支持“CRUDE”,还可以进行**导出到 Excel**。

欢迎随时联系,留下评论/建议。

历史

  • 2019年9月:v1.1 添加了关于 Docker 支持的信息
  • 2019年9月:v1.0 初始版本
© . All rights reserved.