Agregar documentación en formato Swagger en API’s de .Net Core 3.1

En esta ocasión les mostrare como integrar documentación en formato swagger a nuestra API de forma automática.

Iniciamos instalando el siguiente paquete Nuget:

Swashbuckle.AspNetCore -Version 5.0.0-rc2

Posteriormente, en el archivo Startup.cs, incluyes el generador de Swagger en el metodo “ConfigureServices”.

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

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen(c =>
    {                
        c.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "API Product",
                Description = "API Products B2B"
            }
        );

        // 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);
    });
}

Y en el método “Configure” habilitas el middleware de Swagger

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    // 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 =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "API Product V1");
    });

    app.UseHttpsRedirection();
    app.UseMvc();
}

Ahora agregaremos cierta configuración al proyecto de tipo API.

Da clic derecho en el proyecto de tipo API y elige la opción “Edit Project File”, posteriormente, agregar las siguientes líneas:

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

Quedaría de la siguiente forma:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\ARCA.B2B.Product.Domain\ARCA.B2B.Product.Domain.csproj" />
  </ItemGroup>

</Project>

Ahora necesitamos agregar etiquetas de documentación a los controladores y métodos.

En la clase del controlador se agregara el atributo [Produces] para indicar el formato de entrada y salida del API.

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

En los métodos del controlador se agregaran comentarios en formato de triple diagonal

/// <summary>
/// Get all products, optional filter by segment
/// </summary>
/// <remarks>
/// Sample request:
///
///     GET: api/Product
///
/// </remarks>
/// <param name="Segment">1 - Favoritos, 2 - Destacados</param>
/// <response code="200">Return a list of products</response>
/// <response code="204">Products not found</response>
/// <response code="400">Invalid data</response>
// GET: api/Product
[HttpGet]
[ProducesResponseType(typeof(List<Domain.Entities.Product>), 200)]
public IActionResult Get([FromQuery]Domain.Entities.ProductSegment? Segment)
{
    List<Domain.Entities.Product> _products = new List<Domain.Entities.Product>();

    if (Segment != null)
        _products.Add(new Domain.Entities.Product() { ProductId = "001", ShortDesciption = "Coca Cola 600 ml", Favorite = true });
    else
        _products.Add(new Domain.Entities.Product() { ProductId = "001", ShortDesciption = "Coca Cola 600 ml" });

    return Ok(_products);
}

También se agregara la etiqueta [ProducesResponseType] en los métodos que retornen algún tipo de dato, especificando en tipo de dato a retornar y el código HTTP a responder, tiene que corresponder con alguno de los “Response Code” que se agregaron en los comentarios.

[HttpGet]
[ProducesResponseType(typeof(List<Domain.Entities.Product>), 200)]
public IActionResult Get([FromQuery]Domain.Entities.ProductSegment? Segment)

También es recomendable agregar Data Anotation en las entidades, lo cual hace mas descriptiva la presentación de las entidades en Swagger.

using System.ComponentModel.DataAnnotations;


namespace ARCA.B2B.Product.Domain.Entities
{
    public class Favorite
    {
        [Required]
        public int ClientId { get; set; }
        [Required]
        public string ProductId { get; set; }
    }
}

Por ultimo, para consultar la UI de Swagger, partiendo de la siguiente URL del API:

https://localhost:[Port]/api/Product

Se le agrega la siguiente ruta “Swagger/Indez.html” a la URL Root del API

https://localhost:[Port]/Swagger/Index.html

La especificación en formato JSON se consulta igualmente desde el Root agregando “swagger/v1/swagger.json”

https://localhost:[Port]/swagger/v1/swagger.json

Con esto finalizamos, espero les sea de utilidad.

Habilitar CORS en .Net Core 3.1

En esta ocasión les comparto un poco de código sobre como habilitar el intercambio de recursos de origen cruzado (CORS) en un API de .Net Core.

Se habilita agregando las siguientes lineas a los métodos ConfigureServices y Configure del archivo Startup.cs del proyecto.

        public void ConfigureServices(IServiceCollection services)
        {          
            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigin", builder =>
                    builder.AllowAnyHeader()
                           .AllowAnyMethod()
                           .AllowAnyOrigin()
                );
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseCors("AllowAllOrigin");
        }

-Referencia
https://anexsoft.com/netcore-api-vuejs-spa-cors-y-nuestro-primer-listar-con-element-ui