Merge branch 'dev-api-documentation' of rajukottedi/PortBlog.API into dev
This commit is contained in:
commit
46edddc84f
@ -1,4 +1,5 @@
|
||||
using AutoMapper;
|
||||
using Asp.Versioning;
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PortBlog.API.Entities;
|
||||
@ -7,8 +8,9 @@ using PortBlog.API.Repositories.Contracts;
|
||||
|
||||
namespace PortBlog.API.Controllers
|
||||
{
|
||||
[Route("api/cv")]
|
||||
[Route("api/v{versions:apiVersion}/cv")]
|
||||
[ApiController]
|
||||
[ApiVersion(1)]
|
||||
public class CvController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<CvController> _logger;
|
||||
@ -24,7 +26,19 @@ namespace PortBlog.API.Controllers
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get CV details of the candidate by candidateid.
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose cv to get</param>
|
||||
/// <returns>CV details of the candidate</returns>
|
||||
/// <response code="200">Returns the requested cv of the candidate</response>
|
||||
[HttpGet("{candidateId}")]
|
||||
[Obsolete]
|
||||
[ApiVersion(0.1, Deprecated = true)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<ResumeDto>> Get(int candidateId)
|
||||
{
|
||||
try
|
||||
@ -47,7 +61,17 @@ namespace PortBlog.API.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hobbies of the candidate by candidateid
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose hobbies to get</param>
|
||||
/// <returns>Hobbies of the candidate</returns>
|
||||
/// <response code="200">Returns the requested hobbies of the candidate</response>
|
||||
[HttpGet("GetHobbies/{candidateId}")]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<AboutDto>> GetHobbies(int candidateId)
|
||||
{
|
||||
try
|
||||
@ -70,7 +94,17 @@ namespace PortBlog.API.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Candidate details with social links by candidateid
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose detials to get with social links</param>
|
||||
/// <returns>Candidate details with sociallinks</returns>
|
||||
/// <response code="200">Returns the requested candidate details with social links</response>
|
||||
[HttpGet("GetCandidateWithSocialLinks/{candidateId}")]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<CandidateSocialLinksDto>> GetContact(int candidateId)
|
||||
{
|
||||
try
|
||||
@ -93,7 +127,17 @@ namespace PortBlog.API.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Candidate resume by candidateid
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose resume to get</param>
|
||||
/// <returns>Candidate resume</returns>
|
||||
/// <response code="200">Returns the requested candidate resume</response>
|
||||
[HttpGet("GetResume/{candidateId}")]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<ResumeDto>> GetResume(int candidateId)
|
||||
{
|
||||
try
|
||||
@ -116,7 +160,17 @@ namespace PortBlog.API.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Candidate projects by candidateid
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose projects to get</param>
|
||||
/// <returns>Candidate projects</returns>
|
||||
/// <response code="200">Returns the requested candidate projects</response>
|
||||
[HttpGet("GetProjects/{candidateId}")]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<ProjectsDto>> GetProjects(int candidateId)
|
||||
{
|
||||
try
|
||||
@ -139,7 +193,17 @@ namespace PortBlog.API.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Candidate blog with posts by candidateid
|
||||
/// </summary>
|
||||
/// <param name="candidateId">The id of the candidate whose blog with posts to get</param>
|
||||
/// <returns>Candidate blog with posts</returns>
|
||||
/// <response code="200">Returns the requested candidate blog with posts</response>
|
||||
[HttpGet("GetBlog/{candidateId}")]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<BlogDto>> GetBlog(int candidateId)
|
||||
{
|
||||
try
|
||||
|
||||
@ -1,17 +1,33 @@
|
||||
namespace PortBlog.API.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// CV details of the candidate
|
||||
/// </summary>
|
||||
public class ResumeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// The id of the cv
|
||||
/// </summary>
|
||||
public int ResumeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The title of the candidate
|
||||
/// </summary>
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A brief description about the candidate
|
||||
/// </summary>
|
||||
public string About { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Candidate's information
|
||||
/// </summary>
|
||||
public CandidateDto? Candidate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Candidate's Social Media links
|
||||
/// </summary>
|
||||
public SocialLinksDto? SocialLinks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Candidate's blog posts
|
||||
/// </summary>
|
||||
public ICollection<PostDto> Posts
|
||||
{
|
||||
get
|
||||
@ -19,19 +35,33 @@
|
||||
return SocialLinks?.Posts ?? new List<PostDto>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The education details of the candidate
|
||||
/// </summary>
|
||||
public ICollection<AcademicDto> Academics { get; set; } = new List<AcademicDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The skills of the candidate
|
||||
/// </summary>
|
||||
public ICollection<SkillDto> Skills { get; set; } = new List<SkillDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The work experiences of the candidate
|
||||
/// </summary>
|
||||
public ICollection<ExperienceDto> Experiences { get; set; } = new List<ExperienceDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The certifications done by the candidate
|
||||
/// </summary>
|
||||
public ICollection<CertificationDto> Certifications { get; set; } = new List<CertificationDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The hobbies of the candidate
|
||||
/// </summary>
|
||||
public ICollection<HobbyDto> Hobbies { get; set; } = new List<HobbyDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The projects of the candidate
|
||||
/// </summary>
|
||||
public ICollection<ProjectDto> Projects { get; set; } = new List<ProjectDto>();
|
||||
|
||||
/// <summary>
|
||||
/// The project categories of all the projects
|
||||
/// </summary>
|
||||
public ICollection<string> ProjectsCategories
|
||||
{
|
||||
get
|
||||
|
||||
@ -4,9 +4,12 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>PortBlog.API.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
|
||||
174
PortBlog.API/PortBlog.API.xml
Normal file
174
PortBlog.API/PortBlog.API.xml
Normal file
@ -0,0 +1,174 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>PortBlog.API</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.Get(System.Int32)">
|
||||
<summary>
|
||||
Get CV details of the candidate by candidateid.
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose cv to get</param>
|
||||
<returns>CV details of the candidate</returns>
|
||||
<response code="200">Returns the requested cv of the candidate</response>
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.GetHobbies(System.Int32)">
|
||||
<summary>
|
||||
Get hobbies of the candidate by candidateid
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose hobbies to get</param>
|
||||
<returns>Hobbies of the candidate</returns>
|
||||
<response code="200">Returns the requested hobbies of the candidate</response>
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.GetContact(System.Int32)">
|
||||
<summary>
|
||||
Get Candidate details with social links by candidateid
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose detials to get with social links</param>
|
||||
<returns>Candidate details with sociallinks</returns>
|
||||
<response code="200">Returns the requested candidate details with social links</response>
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.GetResume(System.Int32)">
|
||||
<summary>
|
||||
Get Candidate resume by candidateid
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose resume to get</param>
|
||||
<returns>Candidate resume</returns>
|
||||
<response code="200">Returns the requested candidate resume</response>
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.GetProjects(System.Int32)">
|
||||
<summary>
|
||||
Get Candidate projects by candidateid
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose projects to get</param>
|
||||
<returns>Candidate projects</returns>
|
||||
<response code="200">Returns the requested candidate projects</response>
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Controllers.CvController.GetBlog(System.Int32)">
|
||||
<summary>
|
||||
Get Candidate blog with posts by candidateid
|
||||
</summary>
|
||||
<param name="candidateId">The id of the candidate whose blog with posts to get</param>
|
||||
<returns>Candidate blog with posts</returns>
|
||||
<response code="200">Returns the requested candidate blog with posts</response>
|
||||
</member>
|
||||
<member name="T:PortBlog.API.Migrations.InitialDBMigration">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialDBMigration.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialDBMigration.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialDBMigration.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:PortBlog.API.Migrations.InitialSeedData">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialSeedData.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialSeedData.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.InitialSeedData.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:PortBlog.API.Migrations.AddDobToCandidate">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobToCandidate.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobToCandidate.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobToCandidate.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:PortBlog.API.Migrations.AddDobData">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobData.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobData.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:PortBlog.API.Migrations.AddDobData.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:PortBlog.API.Models.ResumeDto">
|
||||
<summary>
|
||||
CV details of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.ResumeId">
|
||||
<summary>
|
||||
The id of the cv
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Title">
|
||||
<summary>
|
||||
The title of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.About">
|
||||
<summary>
|
||||
A brief description about the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Candidate">
|
||||
<summary>
|
||||
Candidate's information
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.SocialLinks">
|
||||
<summary>
|
||||
Candidate's Social Media links
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Posts">
|
||||
<summary>
|
||||
Candidate's blog posts
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Academics">
|
||||
<summary>
|
||||
The education details of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Skills">
|
||||
<summary>
|
||||
The skills of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Experiences">
|
||||
<summary>
|
||||
The work experiences of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Certifications">
|
||||
<summary>
|
||||
The certifications done by the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Hobbies">
|
||||
<summary>
|
||||
The hobbies of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.Projects">
|
||||
<summary>
|
||||
The projects of the candidate
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:PortBlog.API.Models.ResumeDto.ProjectsCategories">
|
||||
<summary>
|
||||
The project categories of all the projects
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@ -1,3 +1,5 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning.ApiExplorer;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.OpenApi.Models;
|
||||
@ -5,6 +7,7 @@ using PortBlog.API.DbContexts;
|
||||
using PortBlog.API.Extensions;
|
||||
using PortBlog.API.Middleware;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
@ -27,8 +30,64 @@ builder.Services.AddProblemDetails();
|
||||
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
|
||||
var connectionString = builder.Configuration.GetConnectionString("PortBlogDBConnectionString");
|
||||
|
||||
if (builder.Configuration.GetValue<bool>("ConnectionStrings:Encryption"))
|
||||
{
|
||||
connectionString = builder.Configuration.DecryptConnectionString(connectionString);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
throw new Exception("Connection string cannot be empty");
|
||||
}
|
||||
|
||||
builder.Services
|
||||
.AddDbContext<CvBlogContext>(dbContextOptions
|
||||
=> dbContextOptions.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||
|
||||
builder.Services.AddRepositories();
|
||||
|
||||
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
||||
|
||||
|
||||
// Registering API Versioning Specification services
|
||||
builder.Services.AddApiVersioning(setupAction =>
|
||||
{
|
||||
setupAction.ReportApiVersions = true;
|
||||
setupAction.AssumeDefaultVersionWhenUnspecified = true;
|
||||
setupAction.DefaultApiVersion = new ApiVersion(1, 0);
|
||||
}).AddMvc()
|
||||
.AddApiExplorer(setupAction =>
|
||||
{
|
||||
setupAction.SubstituteApiVersionInUrl = true;
|
||||
});
|
||||
|
||||
var apiVersionDescriptionProvider = builder.Services.BuildServiceProvider()
|
||||
.GetRequiredService<IApiVersionDescriptionProvider>();
|
||||
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
foreach(var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
|
||||
{
|
||||
c.SwaggerDoc(
|
||||
$"{description.GroupName}",
|
||||
new()
|
||||
{
|
||||
Title = "Portfolio Blog API",
|
||||
Version = description.ApiVersion.ToString(),
|
||||
Description = "Through this API you can access candidate cv details and along with other details."
|
||||
});
|
||||
}
|
||||
|
||||
// XML Comments file for API Documentation
|
||||
var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlCommentsFullPath = $"{Path.Combine(AppContext.BaseDirectory, xmlCommentsFile)}";
|
||||
|
||||
c.IncludeXmlComments(xmlCommentsFullPath);
|
||||
|
||||
// Add Security Definition to the Swagger
|
||||
c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "ApiKey must appear in header",
|
||||
@ -56,26 +115,6 @@ builder.Services.AddSwaggerGen(c =>
|
||||
c.AddSecurityRequirement(requirement);
|
||||
});
|
||||
|
||||
var connectionString = builder.Configuration.GetConnectionString("PortBlogDBConnectionString");
|
||||
|
||||
if (builder.Configuration.GetValue<bool>("ConnectionStrings:Encryption"))
|
||||
{
|
||||
connectionString = builder.Configuration.DecryptConnectionString(connectionString);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
throw new Exception("Connection string cannot be empty");
|
||||
}
|
||||
|
||||
builder.Services
|
||||
.AddDbContext<CvBlogContext>(dbContextOptions
|
||||
=> dbContextOptions.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||
|
||||
builder.Services.AddRepositories();
|
||||
|
||||
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (!app.Environment.IsDevelopment())
|
||||
@ -87,7 +126,16 @@ if (!app.Environment.IsDevelopment())
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseSwaggerUI(setupAction =>
|
||||
{
|
||||
var descriptions = app.DescribeApiVersions();
|
||||
foreach(var description in descriptions)
|
||||
{
|
||||
setupAction.SwaggerEndpoint(
|
||||
$"/swagger/{description.GroupName}/swagger.json",
|
||||
description.GroupName.ToUpperInvariant());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user