Поделиться через


Начало работы с Swashbuckle и ASP.NET Core

Примечание.

Swashbuckle недоступна в .NET 9 и более поздних версиях. Дополнительные сведения см. в разделе "Обзор поддержки OpenAPI" в приложениях API ASP.NET Core.

Swashbuckle состоит из трех ключевых компонентов.

  • Swashbuckle.AspNetCore.Swagger: объектная модель Swagger и ПО промежуточного слоя для предоставления объектов SwaggerDocument как конечных точек JSON.

  • Swashbuckle.AspNetCore.SwaggerGen: генератор Swagger, создающий объекты SwaggerDocument непосредственно из ваших маршрутов, контроллеров и моделей. Обычно его объединяют с промежуточным слоем конечной точки Swagger, чтобы автоматически предоставлять JSON-файл Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: встроенная версия средства пользовательского интерфейса Swagger. Он обрабатывает JSON-файл Swagger, чтобы создать многофункциональный настраиваемый интерфейс, который используется для описания функций веб-API. К нему можно отнести встроенное окружение теста, используемое в открытых методах.

Установка пакета

Swashbuckle можно добавить одним из описанных ниже способов.

  • В окне Консоль диспетчера пакетов

    • Перейдите в раздел Представление>Другие окна>Консоль диспетчера пакетов

    • Перейдите в каталог, в котором .csproj существует файл

    • Выполните следующую команду:

      Install-Package Swashbuckle.AspNetCore -Version 6.6.2
      
  • В диалоговом окне Управление пакетами NuGet

    • Щелкните правой кнопкой мыши проект в обозревателе решений>Управление пакетами NuGet
    • В качестве источника пакета выберите "nuget.org".
    • Убедитесь, что параметр "Включить предварительные выпуски" включен.
    • В поле поиска введите "Swashbuckle.AspNetCore".
    • Выберите последний пакет Swashbuckle.AspNetCore на вкладке Обзор и нажмите кнопку Установить.

Добавление и настройка ПО промежуточного слоя Swagger

Добавьте генератор Swagger в коллекцию служб в методе Program.cs:

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

Вызов AddEndpointsApiExplorer , показанный в предыдущем примере, требуется только для минимальных API. Дополнительные сведения см . в этой записи StackOverflow.

Включите ПО промежуточного слоя для обслуживания созданного документа JSON и пользовательского интерфейса Swagger, а также в Program.cs:

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

Приведенный выше код добавляет ПО промежуточного слоя Swagger только в том случае, если выбрана текущая среда Development (Разработка). Вызов UseSwaggerUI метода включает внедренную версию средства пользовательского интерфейса Swagger.

Запустите приложение и перейдите к файлу https://localhost:<port>/swagger/v1/swagger.json. Появится созданный документ, описывающий конечные точки, как показано в спецификации OpenAPI (openapi.json).

Пользовательский интерфейс Swagger можно найти по адресу https://localhost:<port>/swagger. Изучите API через пользовательский интерфейс Swagger и включите его в другие программы.

Совет

Чтобы предоставить пользовательский интерфейс Swagger в корневом каталоге приложения (https://localhost:<port>/), установите для свойства RoutePrefix пустую строку:

if (builder.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
        options.RoutePrefix = string.Empty;
    });
}

Если вы используете каталоги в службах IIS или на обратном прокси-сервере, задайте для конечной точки Swagger относительный путь с помощью префикса ./. Например, ./swagger/v1/swagger.json. /swagger/v1/swagger.json указывает, что приложение должно искать JSON-файл в реальном корне URL-адреса (с префиксом маршрута, если он используется). Например, используйте функцию https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json вместо https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Примечание.

По умолчанию Swashbuckle генерирует и предоставляет JSON-файл Swagger в версии 3.0 спецификации, которая официально называется OpenAPI. Чтобы обеспечить обратную совместимость, можно предоставлять JSON-файл в формате версии 2.0. Формат 2.0 необходим для интеграции с такими продуктами, как Microsoft Power Apps и Microsoft Flow, которые сейчас поддерживают спецификацию OpenAPI версии 2.0. Чтобы перейти на формат 2.0, задайте свойство SerializeAsV2 в Program.cs следующим образом:

app.UseSwagger(options =>
{
    options.SerializeAsV2 = true;
});

Настройка и расширение

Swagger предоставляет параметры для документирования объектной модели и настройки пользовательского интерфейса в соответствии с вашим фирменным стилем.

Данные и описание API

Действие настройки, передаваемое в метод AddSwaggerGen, можно использовать для добавления сведений об авторе, лицензии и описании.

В Program.cs импортируйте следующие пространства имен для использования в классе OpenApiInfo:

using Microsoft.OpenApi.Models;

С помощью класса OpenApiInfo измените информацию, которая отображается в пользовательском интерфейсе:

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });
});

Пользовательский интерфейс Swagger отображает сведения о версии:

Пользовательский интерфейс Swagger с данными версии: описание, автор и лицензия.

Комментарии XML

XML-комментарии можно включить следующим образом.

  • В обозревателе решений щелкните проект правой кнопкой мыши и выберите команду Edit <project_name>.csproj.
  • Добавьте GenerateDocumentationFile в файл .csproj:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

Включение комментариев XML предоставляет отладочную информацию для недокументированных открытых типов и членов. Недокументированные типы и члены указываются в предупреждающем сообщении. Например, следующее сообщение оповещает о нарушении кода предупреждения 1591:

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController'

Чтобы отключить предупреждения на уровне всего проекта, определите разделенный точками с запятой список игнорируемых кодов предупреждений в файле проекта. Добавление кодов предупреждений в $(NoWarn); также применяется к значениям C# по умолчанию.

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Чтобы отключить предупреждения только для определенных элементов, поместите код в директивы препроцессора #pragma warning. Этот подход полезен для кода, который не должен предоставляться с помощью документации ПО API. В следующем примере код предупреждения CS1591 игнорируется для всего TodoContext класса. Применение кода предупреждения можно восстановить в конце определения класса. Укажите несколько кодов предупреждений в списке, разделив их запятыми.

namespace SwashbuckleSample.Models;

#pragma warning disable CS1591
public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }

    public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591

Настройте Swagger на использование XML-файла, который создается с помощью приведенных выше инструкций. В Linux и других операционных системах, отличных от Windows, имена и пути файлов могут быть чувствительны к регистру. Например, файл действителен в Windows, TodoApi.XML но не Ubuntu.

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });

    // using System.Reflection;
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});

В приведенном выше коде для создания имени XML-файла, соответствующего имени проекта веб-API, используется отражение. Свойство AppContext.BaseDirectory используется для построения пути к XML-файлу. Некоторые функции Swagger (например, схемы входных параметров или методы HTTP и коды ответов из соответствующих атрибутов) работают без использования XML-файла документации. Для большинства функций, включая метод сводки и описания параметров и кодов ответа, использование XML-файла является обязательным.

Добавление комментариев с тройной косой чертой к действию улучшает Swagger UI. Это добавляет описание в заголовок раздела. Добавьте элемент <summary> над действием Delete:

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
    var item = await _context.TodoItems.FindAsync(id);

    if (item is null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(item);
    await _context.SaveChangesAsync();

    return NoContent();
}

Пользовательский интерфейс Swagger отображает внутренний текст элемента <summary> в приведенном выше коде:

Пользовательский интерфейс Swagger с XML-комментарием

Пользовательский интерфейс определяется созданной схемой JSON:

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "schema": {
                "type": "integer",
                "format": "int64"
            }
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
},

Добавьте элемент <remarks> в документацию по методу действия Create. Он дополняет сведения, указанные в элементе <summary>, и предоставляет более надежный пользовательский интерфейс Swagger. Содержимое элемента <remarks> может включать текст, JSON или XML.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

Обратите внимание, как эти дополнительные комментарии улучшают пользовательский интерфейс:

Пользовательский интерфейс Swagger с показанными дополнительными комментариями.

Аннотирование данных

Добавьте к модели атрибуты из пространства имен System.ComponentModel.DataAnnotations, чтобы упростить реализацию компонентов пользовательского интерфейса Swagger.

Добавьте атрибут [Required] к свойству Name класса TodoItem.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace SwashbuckleSample.Models;

public class TodoItem
{
    public long Id { get; set; }

    [Required]
    public string Name { get; set; } = null!;

    [DefaultValue(false)]
    public bool IsComplete { get; set; }
}

Наличие этого атрибута изменяет поведение пользовательского интерфейса и схему базового JSON.

"schemas": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "type": "integer",
                "format": "int64"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "type": "boolean",
                "default": false
            }
        },
        "additionalProperties": false
    }
},

Добавьте к контроллеру API атрибут [Produces("application/json")]. Он позволяет объявить, что действия контроллера поддерживают тип содержимого ответа application/json:

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoController : ControllerBase
{

В раскрывающемся списке Тип носителя этот тип содержимого выбирается по умолчанию для операций контроллера GET.

Пользовательский интерфейс Swagger с типом содержимого ответа по умолчанию

Чем больше заметок к данным используется в веб-API, тем более содержательными и полезными становятся пользовательский интерфейс и страницы справки по API.

Описание типов ответов

Разработчиков, использующих веб-API, больше всего интересуют возвращаемые данные — типы ответов и коды ошибок (если они не стандартны). Типы ответов и коды ошибок обозначаются в комментариях к XML и заметках к данным.

Действие Create в случае успеха возвращает код состояния HTTP 201. Код состояния HTTP 400 возвращается в том случае, когда текст отправленного запроса имеет значение NULL. Без надлежащей документации в пользовательском интерфейсе Swagger пользователь не будет знать, чего ожидать. Эту проблему решает добавление строк, выделенных в следующем примере:

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

Теперь пользовательский интерфейс Swagger четко документирует ожидаемые коды HTTP-ответов.

Пользовательский интерфейс Swagger, показывающий описание класса ответа POST

Соглашения можно использовать в качестве альтернативы явному добавлению элемента [ProducesResponseType] к отдельным действиям. См. сведения см. об использовании соглашений веб-API.

Для поддержки оформления с помощью [ProducesResponseType] пакет Swashbuckle.AspNetCore.Annotations содержит расширения, которые позволяют включить и обогатить метаданные отклика, схемы и параметра.

Настройка пользовательского интерфейса

Стандартный пользовательский интерфейс отличается функциональностью и презентабельностью. Но на страницах документации по API должна быть представлена ваша фирменная символика или тема. Для оформления компонентов Swashbuckle в фирменном стиле необходимо добавить ресурсы для обслуживания статических файлов, а затем построить структуру папок для их размещения.

Включите ПО промежуточного слоя для статических файлов:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapControllers();

Чтобы вставить таблицы стилей CSS, добавьте их в папку wwwroot проекта и укажите относительный путь в параметрах ПО промежуточного слоя:

if (app.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
    {
        options.InjectStylesheet("/swagger-ui/custom.css");
    });
}

Дополнительные ресурсы

Просмотреть или скачать образец кода (описание загрузки)

Swashbuckle состоит из трех ключевых компонентов.

  • Swashbuckle.AspNetCore.Swagger: объектная модель Swagger и ПО промежуточного слоя для предоставления объектов SwaggerDocument как конечных точек JSON.

  • Swashbuckle.AspNetCore.SwaggerGen: генератор Swagger, создающий объекты SwaggerDocument непосредственно из ваших маршрутов, контроллеров и моделей. Обычно его объединяют с промежуточным слоем конечной точки Swagger, чтобы автоматически предоставлять JSON-файл Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: встроенная версия средства пользовательского интерфейса Swagger. Он обрабатывает JSON-файл Swagger, чтобы создать многофункциональный настраиваемый интерфейс, который используется для описания функций веб-API. К нему можно отнести встроенное окружение теста, используемое в открытых методах.

Установка пакета

Swashbuckle можно добавить одним из описанных ниже способов.

  • В окне Консоль диспетчера пакетов

    • Перейдите в раздел Представление>Другие окна>Консоль диспетчера пакетов

    • Перейдите в каталог, в котором TodoApi.csproj существует файл

    • Выполните следующую команду:

      Install-Package Swashbuckle.AspNetCore -Version 5.6.3
      
  • В диалоговом окне Управление пакетами NuGet

    • Щелкните правой кнопкой мыши проект в обозревателе решений>Управление пакетами NuGet
    • В качестве источника пакета выберите "nuget.org".
    • Убедитесь, что параметр "Включить предварительные выпуски" включен.
    • В поле поиска введите "Swashbuckle.AspNetCore".
    • Выберите последний пакет Swashbuckle.AspNetCore на вкладке Обзор и нажмите кнопку Установить.

Добавление и настройка ПО промежуточного слоя Swagger

Добавьте генератор Swagger в коллекцию служб в методе Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen();
}

В методе Startup.Configure включите ПО промежуточного слоя для обслуживания созданного документа JSON и пользовательского интерфейса Swagger:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.)
        app.UseSwaggerUI();
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Примечание.

Swashbuckle обнаруживает маршруты и конечные точки на основе пространства имен Microsoft.AspNetCore.Mvc.ApiExplorer MVC. Если проект вызывает AddMvc, маршруты и конечные точки обнаруживаются автоматически. При вызове AddMvcCore метод AddApiExplorer должен быть вызван явным образом. Дополнительные сведения см. в разделе Swashbuckle, ApiExplorer, and Routing (Swashbuckle, ApiExplorer и маршрутизация).

При разработке предыдущий UseSwaggerUI вызов метода включает внедренную версию средства пользовательского интерфейса Swagger. Это зависит от по промежуточного слоя статических файлов. Если код предназначен для .NET Framework или NET Core 1.x, добавьте в проект пакет NuGet Microsoft.AspNetCore.StaticFiles.

Запустите приложение и перейдите к файлу http://localhost:<port>/swagger/v1/swagger.json. Появится созданный документ, описывающий конечные точки, как показано в спецификации OpenAPI (openapi.json).

Пользовательский интерфейс Swagger можно найти по адресу http://localhost:<port>/swagger. Изучите API через пользовательский интерфейс Swagger и включите его в другие программы.

Совет

Чтобы предоставить пользовательский интерфейс Swagger в корневом каталоге приложения (http://localhost:<port>/), установите для свойства RoutePrefix пустую строку:

// // UseSwaggerUI Protected by if (env.IsDevelopment())
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    c.RoutePrefix = string.Empty;
});

Если вы используете каталоги в службах IIS или на обратном прокси-сервере, задайте для конечной точки Swagger относительный путь с помощью префикса ./. Например, ./swagger/v1/swagger.json. /swagger/v1/swagger.json указывает, что приложение должно искать JSON-файл в реальном корне URL-адреса (с префиксом маршрута, если он используется). Например, используйте функцию http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json вместо http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Примечание.

По умолчанию Swashbuckle генерирует и предоставляет JSON-файл Swagger в версии 3.0 спецификации, которая официально называется OpenAPI. Чтобы обеспечить обратную совместимость, можно предоставлять JSON-файл в формате версии 2.0. Формат 2.0 необходим для интеграции с такими продуктами, как Microsoft Power Apps и Microsoft Flow, которые сейчас поддерживают спецификацию OpenAPI версии 2.0. Чтобы перейти на формат 2.0, задайте свойство SerializeAsV2 в Startup.Configure следующим образом:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger(c =>
        {
            c.SerializeAsV2 = true;
        });

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        // UseSwaggerUI is called only in Development.
        app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Настройка и расширение

Swagger предоставляет параметры для документирования объектной модели и настройки пользовательского интерфейса в соответствии с вашим фирменным стилем.

В классе Startup добавьте следующие пространства имен:

using System;
using System.Reflection;
using System.IO;

Данные и описание API

Действие по настройке, передаваемое в метод AddSwaggerGen, можно использовать для добавления таких сведений, как автор, лицензия и описание:

В классе Startup импортируйте следующие пространства имен для использования в классе OpenApiInfo:

using Microsoft.OpenApi.Models;

С помощью класса OpenApiInfo измените информацию, которая отображается в пользовательском интерфейсе:

// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "A simple example ASP.NET Core Web API",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = new Uri("https://twitter.com/spboyer"),
        },
        License = new OpenApiLicense
        {
            Name = "Use under LICX",
            Url = new Uri("https://example.com/license"),
        }
    });
});

Пользовательский интерфейс Swagger отображает сведения о версии:

Пользовательский интерфейс Swagger с данными версии: описание, автор и ссылка на дополнительные сведения.

Комментарии XML

XML-комментарии можно включить следующим образом.

  • В обозревателе решений щелкните проект правой кнопкой мыши и выберите команду Edit <project_name>.csproj.
  • Вручную добавьте выделенные строки в .csproj файл:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Включение комментариев XML предоставляет отладочную информацию для недокументированных открытых типов и членов. Недокументированные типы и члены указываются в предупреждающем сообщении. Например, следующее сообщение оповещает о нарушении кода предупреждения 1591:

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController.GetAll()'

Чтобы отключить предупреждения на уровне всего проекта, определите разделенный точками с запятой список игнорируемых кодов предупреждений в файле проекта. Добавление кодов предупреждений в $(NoWarn); также применяется к значениям C# по умолчанию.

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Чтобы отключить предупреждения только для определенных элементов, поместите код в директивы препроцессора #pragma warning. Этот подход полезен для кода, который не должен предоставляться с помощью документации ПО API. В следующем примере код предупреждения CS1591 игнорируется для всего Program класса. Применение кода предупреждения можно восстановить в конце определения класса. Укажите несколько кодов предупреждений в списке, разделив их запятыми.

namespace TodoApi
{
#pragma warning disable CS1591
    public class Program
    {
        public static void Main(string[] args) =>
            BuildWebHost(args).Run();

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
#pragma warning restore CS1591
}

Настройте Swagger на использование XML-файла, который создается с помощью приведенных выше инструкций. В Linux и других операционных системах, отличных от Windows, имена и пути файлов могут быть чувствительны к регистру. Например, файл действителен в Windows, TodoApi.XML но не Ubuntu.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo
        {
            Version = "v1",
            Title = "ToDo API",
            Description = "A simple example ASP.NET Core Web API",
            TermsOfService = new Uri("https://example.com/terms"),
            Contact = new OpenApiContact
            {
                Name = "Shayne Boyer",
                Email = string.Empty,
                Url = new Uri("https://twitter.com/spboyer"),
            },
            License = new OpenApiLicense
            {
                Name = "Use under LICX",
                Url = new Uri("https://example.com/license"),
            }
        });

        // Set the comments path for the Swagger JSON and UI.
        var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        c.IncludeXmlComments(xmlPath);
    });
}

В приведенном выше коде для создания имени XML-файла, соответствующего имени проекта веб-API, используется отражение. Свойство AppContext.BaseDirectory используется для построения пути к XML-файлу. Некоторые функции Swagger (например, схемы входных параметров или методы HTTP и коды ответов из соответствующих атрибутов) работают без использования XML-файла документации. Для большинства функций, включая метод сводки и описания параметров и кодов ответа, использование XML-файла является обязательным.

Добавление комментариев с тройной косой чертой к действию улучшает Swagger UI. Это добавляет описание в заголовок раздела. Добавьте элемент <summary> над действием Delete:

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>        
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
    var todo = _context.TodoItems.Find(id);

    if (todo == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todo);
    _context.SaveChanges();

    return NoContent();
}

Пользовательский интерфейс Swagger отображает внутренний текст элемента <summary> в приведенном выше коде:

Пользовательский интерфейс Swagger с XML-комментарием

Пользовательский интерфейс определяется созданной схемой JSON:

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "operationId": "ApiTodoByIdDelete",
    "consumes": [],
    "produces": [],
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "type": "integer",
            "format": "int64"
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
}

Добавьте элемент <remarks> в документацию по методу действия Create. Он дополняет сведения, указанные в элементе <summary>, и предоставляет более надежный пользовательский интерфейс Swagger. Содержимое элемента <remarks> может включать текст, JSON или XML.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Обратите внимание, как эти дополнительные комментарии улучшают пользовательский интерфейс:

Пользовательский интерфейс Swagger с показанными дополнительными комментариями.

Аннотирование данных

Добавьте к модели атрибуты из пространства имен System.ComponentModel.DataAnnotations, чтобы упростить реализацию компонентов пользовательского интерфейса Swagger.

Добавьте атрибут [Required] к свойству Name класса TodoItem.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }

        [Required]
        public string Name { get; set; }

        [DefaultValue(false)]
        public bool IsComplete { get; set; }
    }
}

Наличие этого атрибута изменяет поведение пользовательского интерфейса и схему базового JSON.

"definitions": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "format": "int64",
                "type": "integer"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "default": false,
                "type": "boolean"
            }
        }
    }
},

Добавьте к контроллеру API атрибут [Produces("application/json")]. Он позволяет объявить, что действия контроллера поддерживают тип содержимого ответа application/json:

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
    private readonly TodoContext _context;

В раскрывающемся списке Тип содержимого ответа этот тип содержимого выбирается по умолчанию для операций контроллера GET.

Пользовательский интерфейс Swagger с типом содержимого ответа по умолчанию.

Чем больше заметок к данным используется в веб-API, тем более содержательными и полезными становятся пользовательский интерфейс и страницы справки по API.

Описание типов ответов

Разработчиков, использующих веб-API, больше всего интересуют возвращаемые данные — типы ответов и коды ошибок (если они не стандартны). Типы ответов и коды ошибок обозначаются в комментариях к XML и заметках к данным.

Действие Create в случае успеха возвращает код состояния HTTP 201. Код состояния HTTP 400 возвращается в том случае, когда текст отправленного запроса имеет значение NULL. Без надлежащей документации в пользовательском интерфейсе Swagger пользователь не будет знать, чего ожидать. Эту проблему решает добавление строк, выделенных в следующем примере:

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Теперь пользовательский интерфейс Swagger четко документирует ожидаемые коды HTTP-ответов.

Пользовательский интерфейс Swagger, показывающий описание класса ответа POST

В ASP.NET Core 2.2 или более поздней версии соглашения можно использовать в качестве альтернативы явному добавлению к отдельным действиям элемента [ProducesResponseType]. См. сведения см. об использовании соглашений веб-API.

Для поддержки оформления с помощью [ProducesResponseType] пакет Swashbuckle.AspNetCore.Annotations содержит расширения, которые позволяют включить и обогатить метаданные отклика, схемы и параметра.

Настройка пользовательского интерфейса

Стандартный пользовательский интерфейс отличается функциональностью и презентабельностью. Но на страницах документации по API должна быть представлена ваша фирменная символика или тема. Для оформления компонентов Swashbuckle в фирменном стиле необходимо добавить ресурсы для обслуживания статических файлов, а затем построить структуру папок для их размещения.

Если код предназначен для .NET Framework или NET Core 1.x, добавьте в проект пакет NuGet Microsoft.AspNetCore.StaticFiles:

<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />

Предыдущий пакет NuGet уже установлен, если код предназначен для .NET Core 2.x и используется метапакет.

Включите ПО промежуточного слоя для статических файлов:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();

    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Чтобы вставить таблицы стилей CSS, добавьте их в папку wwwroot проекта и укажите относительный путь в параметрах ПО промежуточного слоя:

if (env.IsDevelopment())
{
    app.UseSwaggerUI(c =>
    {
        c.InjectStylesheet("/swagger-ui/custom.css");
    }
}

Дополнительные ресурсы