Updated project and solution files to rename and restructure `DocumentOperator` to `DocumentService`. Modified project references in `DocumentService.API.csproj`, `DocumentService.Application.csproj`, and `DocumentService.Infrastructure.csproj` to reflect the new naming convention. Updated `DocumentService.sln` to remove old project references, add new ones, and adjust configuration and nested project mappings accordingly. This change aligns the project structure with the new naming convention.
126 lines
5.2 KiB
C#
126 lines
5.2 KiB
C#
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
|
using Microsoft.OpenApi.Models;
|
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
|
|
namespace DocumentService.API.Configuration
|
|
{
|
|
/// <summary>
|
|
/// Swagger document filter that merges operations with same path but different [Consumes] attributes.
|
|
/// Ensures both multipart/form-data and application/json variants are visible in Swagger UI.
|
|
/// </summary>
|
|
public class DualInputDocumentFilter : IDocumentFilter
|
|
{
|
|
private readonly IApiDescriptionGroupCollectionProvider _apiDescriptionProvider;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="DualInputDocumentFilter"/> class.
|
|
/// </summary>
|
|
/// <param name="apiDescriptionProvider">API description provider to access all endpoints</param>
|
|
public DualInputDocumentFilter(IApiDescriptionGroupCollectionProvider apiDescriptionProvider)
|
|
{
|
|
_apiDescriptionProvider = apiDescriptionProvider;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies the filter to merge operations with different content types.
|
|
/// </summary>
|
|
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
|
|
{
|
|
var allApiDescriptions = _apiDescriptionProvider.ApiDescriptionGroups.Items
|
|
.SelectMany(g => g.Items)
|
|
.ToList();
|
|
|
|
// Group by path
|
|
var groupedByPath = allApiDescriptions
|
|
.GroupBy(x => "/" + x.RelativePath)
|
|
.ToList();
|
|
|
|
foreach (var group in groupedByPath)
|
|
{
|
|
var path = group.Key;
|
|
|
|
if (!swaggerDoc.Paths.ContainsKey(path))
|
|
continue;
|
|
|
|
var pathItem = swaggerDoc.Paths[path];
|
|
|
|
// Find multipart and JSON variants
|
|
var multipartDesc = group.FirstOrDefault(x =>
|
|
x.SupportedRequestFormats.Any(f => f.MediaType == "multipart/form-data"));
|
|
|
|
var jsonDesc = group.FirstOrDefault(x =>
|
|
x.SupportedRequestFormats.Any(f => f.MediaType == "application/json"));
|
|
|
|
// If we have both variants, merge them into single operation
|
|
if (multipartDesc != null && jsonDesc != null)
|
|
{
|
|
var httpMethod = multipartDesc.HttpMethod?.ToLowerInvariant();
|
|
OperationType operationType;
|
|
|
|
if (!Enum.TryParse<OperationType>(httpMethod, true, out operationType))
|
|
continue;
|
|
|
|
if (!pathItem.Operations.ContainsKey(operationType))
|
|
continue;
|
|
|
|
var operation = pathItem.Operations[operationType];
|
|
|
|
// Ensure RequestBody exists
|
|
if (operation.RequestBody == null)
|
|
{
|
|
operation.RequestBody = new OpenApiRequestBody
|
|
{
|
|
Required = true,
|
|
Content = new Dictionary<string, OpenApiMediaType>()
|
|
};
|
|
}
|
|
|
|
// Add multipart/form-data if missing
|
|
if (!operation.RequestBody.Content.ContainsKey("multipart/form-data"))
|
|
{
|
|
operation.RequestBody.Content.Add("multipart/form-data", new OpenApiMediaType
|
|
{
|
|
Schema = new OpenApiSchema
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, OpenApiSchema>
|
|
{
|
|
["file"] = new OpenApiSchema
|
|
{
|
|
Type = "string",
|
|
Format = "binary",
|
|
Description = "PDF file to upload"
|
|
}
|
|
},
|
|
Required = new HashSet<string> { "file" }
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add application/json if missing
|
|
if (!operation.RequestBody.Content.ContainsKey("application/json"))
|
|
{
|
|
operation.RequestBody.Content.Add("application/json", new OpenApiMediaType
|
|
{
|
|
Schema = new OpenApiSchema
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, OpenApiSchema>
|
|
{
|
|
["base64Pdf"] = new OpenApiSchema
|
|
{
|
|
Type = "string",
|
|
Format = "byte",
|
|
Description = "Base64-encoded PDF file content"
|
|
}
|
|
},
|
|
Required = new HashSet<string> { "base64Pdf" }
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|