Web API-添加Swagger,SQL Server,记录并导出到Excel

目录

介绍

要求

1.创建一个新的Web API项目

2.将Swagger添加到项目

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

4.登录到SQL Server

5.添加“导出到Excel”

总结


  • 下载MikesBank-239.6 KB

介绍

2016年发布以来,ASP.NET Core取得了惊人的进展,而且每个版本似乎都变得更好,更友好且对开发人员更友好。

Web API是对旧的WCF服务的巨大改进(我们甚至不谈论SOAP ...),并且那里有大量的入门资源。本文只是重新编写轮子而已,它只是您要做的以下步骤的备忘单

  1. 创建一个新的Web API项目
  2. Swagger添加到您的项目
  3. 将项目连接到SQL Server数据库
  4. 将日志添加到项目中,以便所有异常或日志消息都保存在SQL Server表中(而不是转储到IIS .txt日志文件中的某个位置)
  5. CRUDE添加到您的项目。不,那不是错字。我们将拥有常规的Create-Read-Update-Delete函数,以及...只是为了展示它的简单性。我们将添加一个端点,使用Open XML库将数据导出到真实的.xlsx文件,仅此而已。

除了第五项之外,这是我使用每个Web API都要执行的4个步骤,因此我认为最好尽可能快速,轻松地记录需要执行的步骤,我们有更多时间专注于完成实际工作!

现在,我已经提供了一个含有从本文的示例代码的MikesBank.zip文件,但我强烈建议你使用它。

Visual Studio 2017ASP.NET Core几乎每个月都在变化... 从零开始创建自己的项目并遵循这些说明是一个更好的主意,使用Microsoft在阅读本文时提供的任何新模板,而不是使用我提供的示例,在您读完本段时,该示例可能已经过时了一半。

祝您阅读愉快!

要求

要阅读本文,您将需要:

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

我建议您先按照以下说明更新 VS2017.NET Core的副本。在撰写本文时,我尝试导入一个VS2017很高兴接受的nuget软件包,但是随后抛出了很多编译错误,因为该nuget软件包比我的.NET Core版本更高,拒绝使用我的旧版本。

1.创建一个新的Web API项目

这个问题已经讨论了很多次了,我相信大家都知道该怎么做。

  1. 启动Visual Studio 2017,然后选择File\New\Project
  2. Visual C\ .NET Core下,选择“ASP.NET Core Web应用程序,并为您的项目命名(我的名字MikesBank),然后单击OK                   Web API-添加Swagger,SQL Server,记录并导出到Excel_第1张图片
  3. 在下一个屏幕上,确保已选择API,它是一个.NET Core应用程序,然后单击确定

Web API-添加Swagger,SQL Server,记录并导出到Excel_第2张图片

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

如果您在Chrome中运行该项目,则会看到几项JSON数据。

但是,如果您仍在使用Internet Explorer,则可能会收到一条奇怪的消息,询问您是否要从本地主机打开或保存values.json19个字节)? ”是的,这是2019年,而他们仍在这样做。我不知道为什么

作为开发人员,您可以(并且应该)通过添加2010年开始的StackOverflow文章中描述的注册表项来解决此问题。这将使Internet Explorer实际上显示JSON数据,而不是困扰我们。

因此,我们现在有了Web 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页面成为默认页面。因此,当我调试时,URL指向根路径时,将显示Swagger页面,例如:

https://localhost:44350/

6、接下来,我将简单的修改构造函数,并添加一个新的env变量:

public Startup(IHostingEnvironment env, IConfiguration configuration)
{
    Configuration = configuration;
    this.env = env;
}

private IHostingEnvironment env { get; }

有了这个,我们可以对ConfigureServices()函数进行更改:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    var pathIncludeXmlComments = $@"{env.ContentRootPath}\{env.ApplicationName}.xml";
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
        {
            Version = "v1",
            Title = "MikesBank API",
            Description = "For CodeProject"
        });

        if (System.IO.File.Exists(pathIncludeXmlComments))
            c.IncludeXmlComments(pathIncludeXmlComments);
    });
}

这有点臃肿,但是可以解决Swagger的问题。在我们的Web API控制器中添加注释通常很有用,Swagger会在其网页中显示这些注释。但是,如果.XML文件不存在,它会完全崩溃我们的应用程序,所以我非常小心,如果这仅包括注释.xml文件不存在。

7、代码更改都已完成,但是现在,我们只需要对项目设置进行一些更改。再次右键单击您的项目名称,然后选择属性。然后,选择构建选项卡。

8、在错误和警告部分,将“ ;1591” 添加到要忽略的警告列表中。如果我们选择在Web API控制器中添加注释,那就太好了!但是,如果我们还没有添加注释,我不喜欢Visual Studio为我们的代码添加下划线。这不是错误/警告,因此我忽略此警告以忽略此类警告。

1701;1702;1591

9、仍在此屏幕上的输出部分中,选中XML文档文件:” 框。

Web API-添加Swagger,SQL Server,记录并导出到Excel_第3张图片

10、现在,跳至调试选项卡,然后从启动浏览器textbox中删除api/values” ,使其保持空白。

如果现在运行项目,您将看到Swagger网站,以及VS2017为我们创建的示例端点的列表。

Web API-添加Swagger,SQL Server,记录并导出到Excel_第4张图片

看起来不错!如果要运行简单的获取所有值功能,则可以单击第一GET行,单击试用 ”按钮,然后单击执行 ”按钮,然后将看到带有两个内容的像以前一样使用硬编码的值的响应正文。

好的,它不像PostmanFiddler那样复杂,但是它是免费的,友好的并且非常有用。

使Swagger在此页面上包含注释就像在端点上方添加summaryremarks段一样简单:

/// 
/// This is the Summary, describing the endpoint
/// 
/// 
/// These are the Remarks for the endpoint
/// 
[HttpGet]
public ActionResult> Get()
{
    return new string[] { "value1", "value2" };
}

请记住,Swagger本身确实会定期更新,并且在您阅读本文时(或者再次)更新一次,或者,如果您在搜索Swagger代码没有构建/显示时遇到的问题,请查看最新的文档。

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

好的,现在让我们将Web API链接到SQL Server数据库。为此,请再次进入“nuget软件包管理器,搜索并安装以下三个软件包:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.SqlServer.Design

如果您更喜欢剪切而不是搜索,那么另一种方法是单击工具\Nuget软件包管理器\软件包管理器控制台,然后运行以下3个命令:

install-package Microsoft.EntityFrameworkCore.SqlServer
install-package Microsoft.EntityFrameworkCore.Tools
install-package Microsoft.EntityFrameworkCore.SqlServer.Design

无论哪种方式,这都会添加连接到SQL Server所需的3个程序包。

现在,我更喜欢使用数据库优先方法,在该方法中,我已经有一个实时运行的数据库,然后将其链接到我的Web API。在这篇文章中,我已经创建了我的本地服务器上的SQL Server数据库称为Southwind,它包含四个表,LocationDepartmentEmployeeLogging

如果您想继续学习,我提供了一个Southwind.sql ”脚本,它将为您创建该数据库、表和数据。

Web API-添加Swagger,SQL Server,记录并导出到Excel_第5张图片

实际上,我们可以使Visual Studio根据这些表的结构为我们创建类。为此,请打开软件包管理器控制台(单击工具\Nuget软件包管理器\软件包管理器控制台),然后输入以下命令,将您的数据库的连接字符串替换为我的连接字符串:

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

这将为我们神奇地创建一个SouthwindContext类,以及四个类,每个数据库表一个。请注意,如果需要,可以通过使用-Tables参数,然后列出表名称,来要求某些(但不是全部)数据库表为其创建类。

Scaffold-DbContext "Server=localhost;Database=Southwind;
Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer 
-OutputDir Models -Tables "Course","Lesson","User"

另请注意,如果您的代码当前未事先成功构建,则此Scaffold-DbContext命令将不起作用。因此,在运行该命令之前,请检查您的代码是否可以正常构建。

您可以在此处查看其他选项。

接下来,我们需要告知我们的appsettings.json文件有关数据库连接的信息,因此请打开此文件,并将其添加到顶部:

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

现在,打开startup.cs,并将其添加到ConfigureServices()函数中:

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

在继续之前,我们需要确保此代码成功构建,但是现在,由于缺少两个using语句,因此它不会。您可以在Startup.cs顶部手动添加它们:

using Microsoft.EntityFrameworkCore;
using MikesBank.Models;

...或者您可以在上面的代码中单击SouthwindContextUseSqlServer,然后使用“CTRL” +“.”使Visual Studio 为您添加using语句。

如果您尝试再次构建,则它现在应该可以成功构建,我们可以继续。

现在,我们具有将数据库CRUD操作添加到Web API的所有构造块。

删除Controllers文件夹中的ValuesController.cs文件,然后右键单击Controllers文件夹,选择添加\控制器,选择最后一个选项使用实体框架进行操作的API控制器,然后单击添加

现在,您可以选择一个模型,并获取Visual Studio为您创建一组端点。我将选择Employee模型:

Web API-添加Swagger,SQL Server,记录并导出到Excel_第6张图片

然后,单击添加按钮,就这样,我们为其中一个表设置了一组CRUD端点。

我们甚至可以进入控制器文件(在我的示例中为EmployeeController.cs),并修改注释,以使其对Swagger更友好。只需删除现有注释,然后将光标放在[HttpGet]上方的空白行上,键入///Visual Studio将为您提供占位符以键入您的注释。

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

如果我们现在运行项目,将显示Swagger页面,我们可以为Employees端点选择的GET,并获取所有employees列表。

在这一点上,我(个人)会做一个小小的改变:通常情况下,当我得到Employee记录的列表,我不希望包括每条记录的整个层次(其中每个employee属于哪个department,并且这个department所在的location),我只想要Employee记录,仅此而已。

您可以通过打开Employee.cs文件并在virtual字段之前添加[JsonIgnore]来防止序列化整个层次结构(您还需要使用CTRL +“.”技巧来获取Visual Studio为此添加一条using语句)

[JsonIgnore]
public virtual Department Dep { get; set; }
[JsonIgnore]
public virtual Employee EmpManager { get; set; }
[JsonIgnore]
public virtual ICollection InverseEmpManager { get; set; }

您还可以更改Startup.csAddMvc()设置,以防止JSON.Net在获取每个Employee记录的太多父/所有者时有点失控:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .AddJsonOptions(
        options => options.SerializerSettings.ReferenceLoopHandling = 
                               Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );

进行此更改后,我仅收到Employee记录列表,仅此而已。

Web API-添加Swagger,SQL Server,记录并导出到Excel_第7张图片

这就是我们使Web API连接到SQL Server数据库以及向SQL Server数据库读取/写入数据的方式。我很乐意为此效劳,但是正如您所看到的,Visual Studio为我们做了(几乎)所有工作。我们只需要记住要采取的步骤。

4.登录到SQL Server

现在,当发生错误/异常时,我真的不喜欢它,并且错误字符串只是进入存储在IIS服务器上某个位置的一些随机.txt文件。将消息发送到SQL Server上的Logging表要有用得多,因此我们可以跟踪此类问题,也许可以在日志查看器 ”屏幕上列出这些问题,以供管理员跟踪,保存堆栈跟踪等等。

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

当然,我们可以使用第三方(例如nLog)来处理日志,但是就我个人而言,我更喜欢自己做。

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

Web API-添加Swagger,SQL Server,记录并导出到Excel_第8张图片

没有什么复杂的。的Log_Severity,(异常)Log_MessageLog_StackTrace字段将全部来自刚刚发生的任何异常,我有一个Log_Source字段,我们可以填充该字段来说明应用程序的哪个区域引发了异常。

哦,我的Update_Time字段(我的每个表中都有一个)始终包含UTC timezone中的日期时间。我们很可能在不同国家/地区拥有用户,他们希望在当地时间知道何时发生异常。

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

  1. 在我们的项目中创建一个名为LogProvider的新文件夹。
  2. 我提供了一个LogProvider.zip文件,将.zip文件中的4个文件解压缩到该文件夹​​中。
  3. 在这些文件的每个文件中,命名空间当前设置为MikesBank.LogProvider。您将需要将其更改为自己的命名空间(取决于您为项目命名的名称)。
  4. SqlHelper.csDBLogger.cs 文件中,特定于我的Logging数据库表的代码。如果表具有不同的名称或字段,则需要更改此代码。
  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();
}

就是这样!

现在,您可以高兴地滑动是尽可能多的LogInformationLogWarningLogErrors。例如:

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

不过,这只是一个恼人的问题。运行此代码,并调用GET端点之后,我确实在Logging中收到了员工记录的加载列表消息,但我也从幕后获得了大量消息。就个人而言,我发现这些内容使查找我真正感兴趣的Log消息变得异常困难,并且希望将其关闭。

为此,您可以进入appsettings.Development.json文件,并修改MicrosoftSystem库中将包括的日志消息类型。如果将它们更改为Warning,则您的日志将不会填满所有这些额外的Entity Framework消息。

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

显然,这是可选的,也许您会希望在开发版本中看到这些详细信息。由你决定。

最后一件事。

我对某些API的最大烦恼之一是可怕的“HTTP响应500:内部服务器错误。当您自己的API抛出此异常时,通常是因为出了点问题,您的代码也没有费心去解决问题或优雅地处理它。

而且,当然,因为您还没有捕获到异常,所以您当然不会尝试将其发送到日志,以便您的开发人员和支持团队可以调查原因。因此,请将每个端点包装在try...catch中,并确保所有异常消息最终出现在Logging表中。

这很容易做到,但是以后会少掉很多头发。

public async Task>> 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.添加导出到Excel”

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

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

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

有了此文件后,我们就可以开始了。

将导出端点添加到控制器的操作非常简单,只需加载数据,然后调用StreamExcelDocument函数,将要导出的数据和要使用的文件名传递给它即可:

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

多么简单!

Web API-添加Swagger,SQL Server,记录并导出到Excel_第9张图片

作为一个在金融行业工作过的人,让我告诉你,拥有一个简单的、可重用的导出到Excel”功能是非常棒的。这是我的客户要求的第一个功能,每次……他们喜欢自己的Excel

总结

就是这样!

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

你可能感兴趣的:(ASP.NET,CORE,架构及框架,CSharp.NET,Web,API,Swagger,Excel)