ASP.NET Core 2.2 引入了 API 分析器,它有利于提高 API 的文档化,API分析器 可以应用在任何带有 ApiController 特性的 Controller 上,本篇就和大家一起讨论下。

安装 API 分析器

如果你使用的是 ASP.NET Core 2.2 的话,用 Visual Studio 中的 NuGet Package Manager 可视化面板 或者 NuGet Package Manager Console 命令行输入如下命令安装 Api Analyzer。


Install-Package Microsoft.AspNetCore.Mvc.Api.Analyzers

值得注意的是,在 ASP.NET Core 3.0 中已经内置了 Microsoft.AspNetCore.Mvc.Api.Analyzers,所以不需要单独安装。

创建 model 和 repository

生成一个 Author 类,代码如下:


    public class Author
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

为了简单起见,我准备创建一个非常简单的 Repository,不连接数据库,如下代码所示:


    public class AuthorRepository
    {
        List<Author> authors = new List<Author>()
        {
            new Author
            {
                Id = 1,
                FirstName = "Joydip",
                LastName = "Kanjilal"
            },
            new Author
            {
                Id = 2,
                FirstName = "Steve",
                LastName = "Smith"
            }
        };
        public async Task<Author> GetAuthor(int id)
        {           
            var author = authors.FirstOrDefault(a => a.Id == id);
            return await Task.FromResult<Author>(author);
        }
        public async Task<bool> SaveAuthor(Author author)
        {
            var result = authors.Where(a => a.Id == author.Id);
            if(result == null)
            {
                authors.Add(author);
                return await Task.FromResult(true);
            }
            return await Task.FromResult(false);
        }
    }

上面 AuthorRepository 类包含两个方法: GetAuthor() SaveAuthor(),前者用于在集合中返回 author 实例,后者用于将 author 实例插入到集合中。

创建 controller 类

接下来将 DefaultController 改造如下:


    [Route("api/[controller]")]
    [ApiController]
    public class DefaultController : ControllerBase
    {
        AuthorRepository authorRepository = new AuthorRepository();
        [HttpGet("{id}")]
        public async Task<ActionResult<Author>> Get(int id)
        {
            if (id <= 0)
            {
                return BadRequest();
            }
            try
            {
                var author = await authorRepository.GetAuthor(id);
                if (author == null)
                    return NotFound();
                return Ok(author);
            }
            catch
            {
                return BadRequest();
            }
        }
        [HttpPut]
        public async Task<ActionResult<bool>> Put([FromBody] Author author)
        {
            var result = await authorRepository.GetAuthor(author.Id);
            if (result == null)
                return NotFound();
            if (author == null)
            {
                return BadRequest();
            }
            try
            {
                var success = await authorRepository.SaveAuthor(author);
                if (!success)
                    return BadRequest();
                return Ok(author);
            }
            catch
            {
                return BadRequest();
            }
        }
    }

配置 Swagger

然后通过 Nuget 将 Swashbuckle.AspNetCore 引入到项目,从而让 API 文档化。


Install-Package Swashbuckle.AspNetCore

当 Swashbuckle.AspNetCore 安装完毕之后,在 Startup.ConfigureServices 方法中将 Swagger 注入到 IOC 容器中,代码如下:


services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiAnalyzersDemo API",
    Version = "v1"});
});

AddSwaggerGen 扩展方法主要是用来指定 API 文档的元数据,通常情况下还要启动 Swagger UI 来实现可视化,在 Startup.Configure 方法中增加如下代码。


app.UseSwagger();
app.UseSwaggerUI(c =>
{
   c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});

浏览 Swagger UI 端点地址

现在把程序跑起来,输入地址:http://localhost:51787/swagger/index.html, 你会看到如下 API 文档化界面。

值得注意的是,Swagger 默认只会列出 HttpStatus =200 的 Response 信息,如下图:

如果想让 Swagger 多列几种状态,要怎么做呢?你可以在 Action 或者 Controller 上增加几个 StatusCode 状态即可,比如 200,400 和 404 ,修改代码如下:


    [Route("api/[controller]")]
    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]    
    public class DefaultController : ControllerBase
    {
        AuthorRepository authorRepository = new AuthorRepository();
        [HttpGet("{id}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<ActionResult<Author>> Get(int id)
        {
            if (id <= 0)
            {
                return BadRequest();
            }
            try
            {
                var author = await authorRepository.GetAuthor(id);
                if (author == null)
                    return NotFound();
                return Ok(author);
            }
            catch
            {
                return BadRequest();
            }
        }
    }

然后再次执行应用程序看下页面输出。

完整的 分析器 代码

下面是完整的 DefaultController 代码,可供参考。


    [Route("api/[controller]")]   
    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    public class DefaultController : ControllerBase
    {
        AuthorRepository authorRepository = new AuthorRepository();
        [HttpGet("{id}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<ActionResult<Author>> Get(int id)
        {
            if (id <= 0)
            {
                return BadRequest();
            }
            try
            {
                var author = await authorRepository.GetAuthor(id);
                if (author == null)
                    return NotFound();
                return Ok(author);
            }
            catch
            {
                return BadRequest();
            }
        }
        [HttpPut]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<ActionResult<bool>> Put([FromBody] Author author)
        {
            var result = await authorRepository.GetAuthor(author.Id);
            if (result == null)
                return NotFound();
            if (author == null)
            {
                return BadRequest();
            }
            try
            {
                var success = await authorRepository.SaveAuthor(author);
                if (!success)
                    return BadRequest();
                return Ok(author);
            }
            catch
            {
                return BadRequest();
            }
        }
    }

API 分析器 是 ASP.NET Core 的一个非常好的补充,正如我们看到的,你可以利用 API Analyzers 和 Swashbuckle 来生成一个优美的 API 文档,关于 Swashbuckle 更多的知识,参考 github: https://github.com/domaindriv...

译文链接:https://www.infoworld.com/art...

更多高质量干货:参见我的 GitHub: csharptranslate


一线码农
366 声望1.6k 粉丝