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

Авторы: Кристоф Ниенабер (Christoph Nienaber), Рико Сутер (Rico Suter) и Дейв Брок (Dave Brock)

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

NSwag обеспечивает следующие возможности:

  • Работу с пользовательским интерфейсом Swagger и генератором Swagger.
  • Создание гибкого кода.

С NSwag отпадает необходимость в существующем API — вы можете использовать сторонние API, которые содержат Swagger и создают реализацию клиента. NSwag позволяет ускорить цикл разработки и легко адаптироваться к изменениям API.

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

Установите NSwag в:

  • создавать спецификации Swagger для реализованного веб-API;
  • применять пользовательский интерфейс Swagger для просмотра и тестирования веб-API.
  • Обслуживают Redoc, чтобы добавить документацию по API для веб-API.

Чтобы использовать ПО промежуточного слоя NSwag для ASP.NET Core, установите пакет NuGet NSwag.AspNetCore. Этот пакет содержит ПО промежуточного слоя, которое позволяет создавать и использовать спецификацию Swagger, пользовательский интерфейс Swagger (версий 2 и 3) и пользовательский интерфейс ReDoc. NSwag 14 поддерживает только версию 3 спецификации пользовательского интерфейса Swagger.

Чтобы установить пакет NuGet NSwag, воспользуйтесь одним из следующих способов.

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

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

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

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

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

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

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

Добавьте Swagger в приложение ASP.NET Core и настройте это ПО промежуточного слоя, выполнив следующие действия:

  • Добавьте генератор OpenApi в коллекцию служб в Program.cs:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddOpenApiDocument();
  • Включите ПО промежуточного слоя для обслуживания созданной спецификации OpenApi, пользовательского интерфейса Swagger и пользовательского интерфейса Redoc, а также в Program.cs:
if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi(); // UseSwaggerUI Protected by if (env.IsDevelopment())
}
  • запуск приложения; Перейдите к:
    • http://localhost:<port>/swagger для просмотра пользовательского интерфейса Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json для просмотра спецификации Swagger.

Создание кода

Можно воспользоваться преимуществами создания кода в NSwag, выбрав один из следующих вариантов:

Создание кода с помощью NSwagStudio

  • Установите NSwagStudio, следуя инструкциям из репозитория NSwagStudio на веб-сайте GitHub. На странице выпуска NSwag можно скачать версию xcopy, которую можно запустить без прав установки и прав администратора.
  • Запустите NSwagStudio и введите swagger.json URL-адрес файла в текстовом поле URL-адрес спецификации Swagger. Например, http://localhost:5232/swagger/v1/swagger.json.
  • Нажмите кнопку Create local Copy (Создать локальную копию), чтобы создать представление JSON своей спецификации Swagger.

NSwag Studio импортирует спецификацию и экспортирует клиент CSharp.

  • В области Outputs (Выходные данные) установите флажок CSharp Client (Клиент CSharp). В зависимости от проекта вы также можете выбрать TypeScript Client (Клиент TypeScript) или CSharp Web API Controller (Контроллер веб-API CSharp). Если выбрать CSharp Web API Controller (Контроллер веб-API CSharp), служба будет перестроена по спецификации посредством обратного создания.
  • Щелкните Generate Outputs (Создать выходные данные), чтобы создать полную клиентскую реализацию проекта TodoApi.NSwag на языке C#. Откройте вкладку CSharp Client (Клиент CSharp), чтобы просмотреть созданный клиентский код.
namespace MyNamespace
{
    using System = global::System;

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.1.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
    public partial class TodoClient
    {
    #pragma warning disable 8618 // Set by constructor via BaseUrl property
        private string _baseUrl;
    #pragma warning restore 8618 // Set by constructor via BaseUrl property
        private System.Net.Http.HttpClient _httpClient;
        private static System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings, true);

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            BaseUrl = "http://localhost:5232";
            _httpClient = httpClient;
        }

        private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
        {
            var settings = new Newtonsoft.Json.JsonSerializerSettings();
            UpdateJsonSerializerSettings(settings);
            return settings;
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set
            {
                _baseUrl = value;
                if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/"))
                    _baseUrl += '/';
            }
        }
        // code omitted for brevity

Совет

Код клиента C# создается на основе выбранных элементов на вкладке "Параметры ". Измените параметры для выполнения таких задач, как переименование и синхронное создание метода пространства имен по умолчанию.

  • Скопируйте созданный код на C# в файл в проекте клиента, который будет использовать API.
  • Начните использовать веб-API:
var todoClient = new TodoClient(new HttpClient());

// Gets all to-dos from the API
var allTodos = await todoClient.GetAsync();

// Create a new TodoItem, and save it via the API.
await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Настройка документирования для API

OpenApi предоставляет варианты документирования объектной модели, чтобы упростить использование веб-API.

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

В Program.csэтой статье обновите AddOpenApiDocument сведения о документе веб-API и включите дополнительные сведения, такие как автор, лицензия и описание. NSwag Сначала импортируйте пространство имен для использования OpenApi классов.

using NSwag;

var builder = WebApplication.CreateBuilder(args);

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

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

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

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

Чтобы включить комментарии XML, выполните следующие действия:

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

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

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

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

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

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

namespace NSwagSample.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

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

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

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

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

namespace NSwagSample.Models;

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

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

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

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

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

Чем больше заметок к данным используется в веб-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 (и xml-комментарии также отображаются):

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

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

Redoc

Redoc — это альтернатива пользовательскому интерфейсу Swagger. Это аналогично, так как она также предоставляет страницу документации для веб-API с помощью спецификации OpenAPI. Разница заключается в том, что пользовательский интерфейс Redoc больше ориентирован на документацию и не предоставляет интерактивный пользовательский интерфейс для тестирования API.

Чтобы включить Redoc, добавьте в нее по промежуточному слоям Program.cs:

if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi(); // UseSwaggerUI is called only in Development.
    
    // Add ReDoc UI to interact with the document
    // Available at: http://localhost:<port>/redoc
    app.UseReDoc(options =>
    {
        options.Path = "/redoc";
    });
}

Запустите приложение и перейдите к http://localhost:<port>/redoc просмотру пользовательского интерфейса Redoc:

Документация по Redoc для примера API.

Авторы: Кристоф Ниенабер (Christoph Nienaber), Рико Сутер (Rico Suter) и Дейв Брок (Dave Brock)

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

NSwag обеспечивает следующие возможности:

  • Работу с пользовательским интерфейсом Swagger и генератором Swagger.
  • Создание гибкого кода.

С NSwag отпадает необходимость в существующем API — вы можете использовать сторонние API, которые содержат Swagger и создают реализацию клиента. NSwag позволяет ускорить цикл разработки и легко адаптироваться к изменениям API.

Регистрация ПО промежуточного слоя NSwag

Зарегистрируйте ПО промежуточного слоя NSwag, чтобы выполнять следующие задачи:

  • создавать спецификации Swagger для реализованного веб-API;
  • применять пользовательский интерфейс Swagger для просмотра и тестирования веб-API.

Чтобы использовать ПО промежуточного слоя NSwag для ASP.NET Core, установите пакет NuGet NSwag.AspNetCore. Этот пакет содержит ПО промежуточного слоя, которое позволяет создавать и использовать спецификацию Swagger, пользовательский интерфейс Swagger (версий 2 и 3) и пользовательский интерфейс ReDoc.

Чтобы установить пакет NuGet NSwag, воспользуйтесь одним из следующих способов.

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

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

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

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

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

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

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

Добавьте Swagger в приложение ASP.NET Core и настройте это ПО промежуточного слоя, выполнив следующие действия:

  • Используя метод Startup.ConfigureServices, зарегистрируйте необходимые службы Swagger:
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddMvc();

    // Register the Swagger services
    services.AddSwaggerDocument();
}
  • В методе Startup.Configure включите ПО промежуточного слоя для обслуживания созданной спецификации Swagger и пользовательского интерфейса Swagger:
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // Register the Swagger generator and the Swagger UI middlewares
    app.UseOpenApi();
    app.UseOpenApi();
    if (env.IsDevelopment())
    {
        app.UseSwaggerUi3();
    }
    app.UseMvc();
}
  • запуск приложения; Перейдите к:
    • http://localhost:<port>/swagger для просмотра пользовательского интерфейса Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json для просмотра спецификации Swagger.

Создание кода

Можно воспользоваться преимуществами создания кода в NSwag, выбрав один из следующих вариантов:

Создание кода с помощью NSwagStudio

  • Установите NSwagStudio, следуя инструкциям из репозитория NSwagStudio на веб-сайте GitHub. На странице выпуска NSwag можно скачать версию xcopy, которую можно запустить без установки и прав администратора.

  • Запустите NSwagStudio и введите swagger.json URL-адрес файла в текстовом поле URL-адрес спецификации Swagger. Например, http://localhost:44354/swagger/v1/swagger.json.

  • Нажмите кнопку Create local Copy (Создать локальную копию), чтобы создать представление JSON своей спецификации Swagger.

    Создание локальной копии спецификация Swagger

  • В области Outputs (Выходные данные) установите флажок CSharp Client (Клиент CSharp). В зависимости от проекта вы также можете выбрать TypeScript Client (Клиент TypeScript) или CSharp Web API Controller (Контроллер веб-API CSharp). Если выбрать CSharp Web API Controller (Контроллер веб-API CSharp), служба будет перестроена по спецификации посредством обратного создания.

  • Щелкните Generate Outputs (Создать выходные данные), чтобы создать полную клиентскую реализацию проекта TodoApi.NSwag на языке C#. Откройте вкладку CSharp Client (Клиент CSharp), чтобы просмотреть созданный клиентский код.

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

namespace MyNamespace
{
    #pragma warning disable

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class TodoClient
    {
        private string _baseUrl = "https://localhost:44354";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient;
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() =>
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        // code omitted for brevity

Совет

Код клиента C# создается на основе выбранных элементов на вкладке "Параметры ". Измените параметры для выполнения таких задач, как переименование и синхронное создание метода пространства имен по умолчанию.

  • Скопируйте созданный код на C# в файл в проекте клиента, который будет использовать API.
  • Начните использовать веб-API:
 var todoClient = new TodoClient();

// Gets all to-dos from the API
 var allTodos = await todoClient.GetAllAsync();

 // Create a new TodoItem, and save it via the API.
var createdTodo = await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Настройка документирования для API

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

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

В методе Startup.ConfigureServices действие по настройке, передаваемое в метод AddSwaggerDocument, можно использовать для добавления таких сведений, как автор, лицензия и описание:

services.AddSwaggerDocument(config =>
{
    config.PostProcess = document =>
    {
        document.Info.Version = "v1";
        document.Info.Title = "ToDo API";
        document.Info.Description = "A simple ASP.NET Core web API";
        document.Info.TermsOfService = "None";
        document.Info.Contact = new NSwag.OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = "https://twitter.com/spboyer"
        };
        document.Info.License = new NSwag.OpenApiLicense
        {
            Name = "Use under LICX",
            Url = "https://example.com/license"
        };
    };
});

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

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

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

Чтобы включить комментарии XML, выполните следующие действия:

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

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

Так как NSwag использует отражение, а рекомендуемый тип возвращаемого значения для действий веб-API — это IActionResult<T>, NSwag может определить только тип возвращаемого значения, задаваемый T. Невозможно автоматически определить другие возможные типы возвращаемого значения.

Рассмотрим следующий пример:

[HttpPost]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

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

Предыдущее действие возвращает ActionResult<T>. Внутри действия возвращается CreatedAtRoute. Так как контроллер имеет атрибут [ApiController], ответ BadRequest также возможен. Дополнительные сведения см. в разделе Автоматические отклики HTTP 400. Используйте заметки к данным для сообщения клиентам о том, какие коды состояний HTTP возвращает это действие. Пометьте действие следующими атрибутами:

[ProducesResponseType(StatusCodes.Status201Created)]     // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)]  // BadRequest

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

Генератор Swagger теперь может точно описать это действие, и созданные клиенты знают, что они получают при вызове конечной точки. Рекомендуется помечать этими атрибутами все действия.

Рекомендации по тому, какие http-ответы должны возвращать действия API, см. в статье RFC 9110: семантика HTTP (раздел 9.3. Определения методов).