Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

(#641) Fixed Swashbuckle generation with route parameters #643

Merged
merged 2 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
Expand Down Expand Up @@ -39,7 +40,7 @@ private enum OpType
/// <summary>
/// The assembly to query for TableController instances, if any. If none is provided, the calling assembly is queried.
/// </summary>
private Assembly assemblyToQuery = null;
private readonly Assembly assemblyToQuery = null;

/// <summary>
/// Creates a new <see cref="DatasyncDocumentFilter"/>.
Expand Down Expand Up @@ -68,11 +69,11 @@ public void Apply(OpenApiDocument document, DocumentFilterContext context)
if (entityType == null)
continue;

var routeAttribute = controller.GetCustomAttribute<RouteAttribute>();
if (routeAttribute == null)
var routePath = context.ApiDescriptions.FirstOrDefault(m => IsApiDescriptionForController(m, controller))?.RelativePath;
if (routePath == null)
continue;
var allEntitiesPath = $"/{routeAttribute.Template}";
var singleEntityPath = $"/{routeAttribute.Template}/{{id}}";
var allEntitiesPath = $"/{routePath}";
var singleEntityPath = $"/{routePath}/{{id}}";

// Get the various operations
Dictionary<OpType, OpenApiOperation> operations = new()
Expand Down Expand Up @@ -176,6 +177,21 @@ public void Apply(OpenApiDocument document, DocumentFilterContext context)
}
}
}

/// <summary>
/// Determines if the controller type is represented by the API Description.
/// </summary>
/// <param name="description">The <see cref="ApiDescription"/> being handled.</param>
/// <param name="controllerType">The type of the controller being used.</param>
/// <returns><c>true</c> if the Api description represents the controller.</returns>
internal static bool IsApiDescriptionForController(ApiDescription description, Type controllerType)
{
if (description.TryGetMethodInfo(out MethodInfo methodInfo))
{
return methodInfo.ReflectedType == controllerType && (methodInfo.Name.Equals("GetAsync") || methodInfo.Name.Equals("CreateAsync"));
}
return false;
}

/// <summary>
/// Returns a list of all table controllers in the provided assembly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

namespace Microsoft.AspNetCore.Datasync.NSwag.Test.Service
{
/// <summary>
/// A model used for validation tests. It contains one of
/// every single supported type in a nullable form.
/// </summary>
[ExcludeFromCodeCoverage]
public class TodoItem : EntityTableData
{
public string? Title { get; set; }
}

[ExcludeFromCodeCoverage]
public class KitchenSink : EntityTableData
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public ServiceDbContext(DbContextOptions<ServiceDbContext> options) : base(optio
/// </summary>
public DbSet<KitchenSink> KitchenSinks => Set<KitchenSink>();

/// <summary>
/// The set of TodoItem values
/// </summary>
public DbSet<TodoItem> TodoItems => Set<TodoItem>();

/// <summary>
/// Initializes the current database
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved.
// Licensed under the MIT License.

using Microsoft.AspNetCore.Datasync.EFCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.AspNetCore.Datasync.NSwag.Test.Service
{
[Route("tables/[controller]")]
[ExcludeFromCodeCoverage]
public class TodoItemController : TableController<TodoItem>
{
public TodoItemController(ServiceDbContext context, ILogger<TodoItem> logger) : base()
{
Repository = new EntityTableRepository<TodoItem>(context);
Logger = logger;
}
}
}
Loading