Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
На заметку! Предупреждения 1701 и 1702 являются пережитками ранних дней классической платформы .NET, которые обнажают компиляторы .NET Core. Чтобы взглянуть на процесс в действии, модифицируйте метод Get() класса ValuesController следующим образом:
/// <summary>
/// This is an example Get method returning JSON
/// </summary>
/// <remarks>This is one of several examples for returning JSON:
/// <pre>
/// [
/// "value1",
/// "value2"
/// ]
/// </pre>
/// </remarks>
/// <returns>List of strings</returns>
[HttpGet]
public IActionResult Get()
{
return Ok(new string[] { "value1", "value2" });
}
Когда вы скомпилируете проект, в корневом каталоге проекта появится новый файл по имени AutoLot.Api.xml. Открыв его, вы увидите только что добавленные комментарии:
<?xml version="1.0"?>
<doc>
<assembly>
<name>AutoLot.Api</name>
</assembly>
<members>
<member name="M:AutoLot.Api.Controllers.ValuesController.Get">
<summary>
This is an example Get method returning JSON
</summary>
<remarks>This is one of several examples for returning JSON:
<pre>
[
"value1",
"value2"
]
</pre>
</remarks>
<returns>List of strings</returns> </member>
</members>
</doc>
На заметку! Если вы вводите три символа прямой косой черты перед определением класса или метода в Visual Studio, то среда создает начальную заглушку для XML-комментариев.
Далее необходимо объединить XML-комментарии со сгенерированным файлом swagger.json.
Добавление XML-комментариев в процесс генерации Swagger
Сгенерированные XML-комментарии должны быть добавлены в процесс генерации swagger.json. Начните с добавления следующих операторов using в файл класса Startup.cs:
using System.IO;
using System.Reflection;
Файл XML-документации добавляется в Swagger вызовом метода IncludeXmlComments() внутри метода AddSwaggerGen(). Перейдите к методу ConfigureServices() класса Startup и модифицируйте метод AddSwaggerGen(), добавив файл XML-документации:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1",
new OpenApiInfo
{
Title = "AutoLot Service",
Version = "v1",
Description = "Service to support the AutoLot dealer site",
License = new OpenApiLicense
{
Name = "Skimedic Inc",
Url = new Uri("http://www.skimedic.com")
}
});
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
Запустите приложение и загляните в пользовательский интерфейс Swagger. Обратите внимание на XML-комментарии, интегрированные в пользовательский интерфейс Swagger (рис. 30.4).
Помимо XML-документации документирование может быть улучшено дополнительной конфигурацией конечных точек приложения.
Дополнительные возможности документирования для конечных точек API
Существуют дополнительные атрибуты, которые дополняют документацию Swagger. Чтобы применить их, начните с добавления показанных далее операторов using в файл ValuesController.cs:
using Microsoft.AspNetCore.Http;
using Swashbuckle.AspNetCore.Annotations;
Атрибут Produces задает тип содержимого для конечной точки. Атрибут ProducesResponseType использует перечисление StatusCodes для указания возможного кода возврата для конечной точки. Модифицируйте метод Get() класса ValuesController, чтобы установить application/json в качестве возвращаемого типа и сообщить о том, что результатом действия будет либо 200 (ОК), либо 400 (Bad Request):
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] {"value1", "value2"};
}
Хотя атрибут ProducesResponseType добавляет в документацию коды ответов, настроить эту информацию невозможно. К счастью, Swashbuckle добавляет атрибут SwaggerResponse, предназначенный как раз для такой цели. Приведите код метода Get() к следующему виду:
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[SwaggerResponse(200, "The execution was successful")]
[SwaggerResponse(400, "The request was invalid")]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] {"value1", "value2"};
}
Прежде чем аннотации Swagger будут приняты и добавлены в сгенерированную документацию, их потребуется включить. Откройте файл Startup.cs и перейдите к методу Configure(). Обновите вызов AddSwaggerGen(), как показано ниже:
services.AddSwaggerGen(c =>
{
c.EnableAnnotations();
...
});
Теперь, просматривая раздел ответов в пользовательском интерфейсе Swagger, вы будете видеть настроенный обмен сообщениями (рис. 30.5).
На заметку! В Swashbuckle поддерживается большой объем дополнительной настройки, за сведениями о которой обращайтесь в документацию по ссылке https://github.com/domaindrivendev/Swashbuckle.AspNetCore.
Построение методов действий API
Большинство функциональных средств приложения AutoLot.Api можно отнести к одному из перечисленных далее методов:
• GetOne()
• GetAll()
• UpdateOne()
• AddOnе()
• DeleteOne()
Основные методы API будут реализованы в обобщенном базовом контроллере API. Начните с создания нового каталога под названием Base в каталоге Controllers проекта AutoLot.Api. Добавьте в этот каталог новый файл класса по имени BaseCrudController.cs. Модифицируйте операторы using и определение класса, как демонстрируется ниже:
using System;
using System.Collections.Generic;
using AutoLot.Dal.Exceptions;
using AutoLot.Models.Entities.Base;
using AutoLot.Dal.Repos.Base;
using AutoLot.Services.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
namespace AutoLot.Api.Controllers.Base
{
[ApiController]
public abstract class BaseCrudController<T, TController> : ControllerBase
where T : BaseEntity, new()
where TController : BaseCrudController<T, TController>
{
}
}
Класс является открытым и абстрактным, а также унаследованным от ControllerBase. Он принимает два обобщенных параметра типа. Первый тип ограничивается так, чтобы быть производным от BaseEntity и иметь стандартный конструктор, а второй — быть производным от BaseCrudController (для представления производных контроллеров). Когда к базовому классу добавляется атрибут ApiController, производные контроллеры получают функциональность, обеспечиваемую атрибутом.
На заметку! Для этого класса не определен маршрут. Он будет установлен с использованием производных классов.
Конструктор
На следующем шаге добавляются две защищенные переменные уровня класса: одна для хранения реализации интерфейса IRepo<T> и еще одна для хранения реализации интерфейса IAppLogging<T>. Обе они должны устанавливаться с применением конструктора.