Skip to content

Commit

Permalink
Added a compatibility fix for a bug in Swagger UI
Browse files Browse the repository at this point in the history
Added a compatibility fix for a bug in Swagger UI where if you use
OpenAPI 3, arrays sent as form fields are sent as comma-separated lists
instead of one element per field.

swagger-api/swagger-ui#10221

Changed AddPost back to accept forms since it will need to accept file
uploads in the future.
  • Loading branch information
palapapa committed Dec 1, 2024
1 parent adeb164 commit 5613cb2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
13 changes: 9 additions & 4 deletions backend/Sources/Controllers/PostsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public async Task<ActionResult<IEnumerable<PostQueryResponseDto>>> GetPostsByPar
[ProducesResponseType(Status401Unauthorized)]
[ProducesResponseType(Status500InternalServerError)]
[Authorize]
public async Task<IActionResult> AddPost(PostSubmissionDto post)
public async Task<IActionResult> AddPost([FromForm] PostSubmissionDto post)
{
Claim? userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
if (userIdClaim is null)
Expand All @@ -109,8 +109,12 @@ public async Task<IActionResult> AddPost(PostSubmissionDto post)
{
return Problem("The account of the currently logged in user has been deleted.", statusCode: Status401Unauthorized);
}
await AddMissingTagsToDb(post.Tags);
ICollection<Tag> tags = await context.Tags.Where(tag => post.Tags.Contains(tag.Name)).ToListAsync();
// This is a compatibility fix for a bug in Swagger UI where if you use OpenAPI 3, arrays sent as form fields are sent as comma-separated lists instead of one element per field.
// https://github.com/swagger-api/swagger-ui/issues/10221
IEnumerable<string> tagsString = post.Tags.SelectMany(tag => tag.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries));
await AddMissingTagsToDb(tagsString);
// Since AddMissingTagsToDb never adds duplicate tags to the DB, this part will also not have duplicate tags.
ICollection<Tag> tags = await context.Tags.Where(tag => tagsString.Contains(tag.Name)).ToListAsync();
Post newPost = new()
{
Author = author,
Expand All @@ -125,9 +129,10 @@ public async Task<IActionResult> AddPost(PostSubmissionDto post)
return CreatedAtAction(nameof(GetPostById), new { id = newPost.Id }, null);
}

private async Task AddMissingTagsToDb(ICollection<string> tagsToAddToNewPost)
private async Task AddMissingTagsToDb(IEnumerable<string> tagsToAddToNewPost)
{
IEnumerable<string> existingTagNames = context.Tags.Where(tag => tagsToAddToNewPost.Contains(tag.Name)).Select(tag => tag.Name);
// Except only returns unique elements, so we will never add duplicate tags.
IEnumerable<string> missingTagNames = tagsToAddToNewPost.Except(existingTagNames);
TagType topicTagType = new() { Id = TagTypeId.Topic, Name = "topic" };
context.TagTypes.Attach(topicTagType);
Expand Down
2 changes: 1 addition & 1 deletion backend/Sources/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private static void Main(string[] args)
.AddDbContext<CitizenProposalAppDbContext>()
.AddProblemDetails()
.AddAutoMapper(config => config.AddProfile<AutoMapperProfile>())
.AddOpenApiDocument()
.AddOpenApiDocument(options => options.Title = "Citizen Proposal App")
.AddSingleton(TimeProvider.System)
.AddControllers()
.AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
Expand Down

0 comments on commit 5613cb2

Please sign in to comment.