Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: /swagger/index.html website is frozen when provided specific argument from route as a SwaggerParameter #3083

Open
PFYasu opened this issue Sep 27, 2024 · 1 comment
Labels

Comments

@PFYasu
Copy link

PFYasu commented Sep 27, 2024

Describe the bug

Hello,

Below is my endpoint signature:

        [SwaggerOperation(
            Summary = "Terminate product",
            OperationId = SwaggerOperationIds.Products.Terminate,
            Tags = [SwaggerTags.Products]
        )]
        [SwaggerResponseAccepted]
        [SwaggerResponseBadRequest]
        [SwaggerResponseUnauthorized]
        [SwaggerResponseNotFound]
        [SwaggerResponseGone]
        [AuditLog]
        [Route("/api/v1/products/terminate/{id}")]
        [HttpPost]
        public async Task<IActionResult> Terminate(
            [SwaggerParameter("Product ID", Required = true)][FromRoute] MyType<Product> id,
            [SwaggerParameter("Terminate product request", Required = false)][FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] TerminateProductRequest request)
        {
           ...

And this is the MyType class:

public class MyType<TType>
{
    public Type Value => typeof(TType);
}

For this configuration I've got an infinity loop in SwaggerGenerator class.

private (IEnumerable<ApiDescription>, OpenApiDocument, SchemaRepository) GetSwaggerDocumentWithoutFilters(string documentName, string host = null, string basePath = null)
        {
            if (!_options.SwaggerDocs.TryGetValue(documentName, out OpenApiInfo info))
                throw new UnknownSwaggerDocument(documentName, _options.SwaggerDocs.Select(d => d.Key));

            // THE LOOP IS IN THE METHOD BELOW AND IT CONSUMES ALL OF MY RAM (after 1 minute of request processing, it ate ~ 20 GB of RAM)

            var applicableApiDescriptions = _apiDescriptionsProvider.ApiDescriptionGroups.Items  
                .SelectMany(group => group.Items)
                .Where(apiDesc =>
                {
                    var attributes = apiDesc.CustomAttributes().ToList();
                    return !(_options.IgnoreObsoleteActions && attributes.OfType<ObsoleteAttribute>().Any()) &&
                           !attributes.OfType<SwaggerIgnoreAttribute>().Any() &&
                           _options.DocInclusionPredicate(documentName, apiDesc);
                });

            var schemaRepository = new SchemaRepository(documentName);

            var swaggerDoc = new OpenApiDocument
            {
                Info = info,
                Servers = GenerateServers(host, basePath),
                Paths = GeneratePaths(applicableApiDescriptions, schemaRepository),
                Components = new OpenApiComponents
                {
                    Schemas = schemaRepository.Schemas,
                },
                SecurityRequirements = new List<OpenApiSecurityRequirement>(_options.SecurityRequirements)
            };

            return (applicableApiDescriptions, swaggerDoc, schemaRepository);
        }

Note in the class ctor I cannot read ApiDescriptionGroups from ApiDescriptionProvider.

image

If I change my affected class a bit as shown below:

public class MyType<TType>
{
    public Type Value = typeof(TType);  // CHANGED `=>` to `=`
}

everything works fine

image

Expected behavior

Swagger should load the page with endpoint descriptions.

Actual behavior

It is spinning and consuming RAM
image

Steps to reproduce

No response

Exception(s) (if any)

No response

Swashbuckle.AspNetCore version

6.6.2

.NET Version

.NET 8.0

Anything else?

No response

@PFYasu PFYasu added the bug label Sep 27, 2024
@martincostello
Copy link
Collaborator

Annotate the property (as I assume it's for use server-side, not for clients in your contract) with the [JsonIgnore] attribute so that you aren't trying to represent a System.Type in your schema (because that's never going to work).

I'm reasonably confident this is an issue with your code (trying to put things that shouldn't be in the OpenAPI document into the OpenAPI document) and not a bug in either Swashbuckle nor swagger-ui.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants