3

There are currently ways to add parameters to every path via Swashbuckle. Some such way can be found here.

Let's say I want to add a parameter to every path called 'api-version'. Then this parameter will appear in every path in the Swagger file.

I want Swashbuckle to generate a single global parameter. For example, instead of this

{
    "swagger": "2.0",
    "paths": {
      "/something": {
        "post": {
          "operationId": "something_do",
          "parameters": [
            {
              "name": "api-version",
              "in": "query",
              "description": "The API version.",
              "required": true,
              "type": "string"
            }
          ],
          "responses": {
            "200": {
              "description": "Something got done.",
              "schema": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }

, I want

{
    "swagger": "2.0",
    "paths": {
        "/something": {
            "post": {
                "operationId": "something_do",
                "responses": {
                    "200": {
                        "description": "Something got done.",
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    },
    "parameters": {
        "ApiVersionParameter": {
            "name": "api-version",
            "in": "query",
            "required": true,
            "type": "string",
            "description": "The API version."
        }
    }
}

with the parameter set globally, and not under every path. I'm unable to find anything under SwaggerGenOptions that produces this.

  • 1
    Just to clarify - parameters defined in the global `parameters` section (in OAS2) or the `components/parameters` section (in OAS3) - like in your second example - are NOT automatically applied to all operations. These parameter definitions need to be explicitly $ref'erenced in operations in order to be actually used. – Helen Jul 07 '20 at 20:19
  • That link you provide uses an `IOperationFilter` there are also `IDocumentFilter` that one you have access to modify the entire document... try that and let us know if you get stuck – Helder Sepulveda Jul 10 '20 at 13:11

1 Answers1

4

Thank you Helder. The IDocumentFilter works.

public class GlobalParameterDocumentFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            if (swaggerDoc != null && swaggerDoc.Components != null)
            {
                swaggerDoc.Components.Parameters.Add(ApiConstants.ApiVersionGlobalParamName, new OpenApiParameter
                {
                    Name = "api-version",
                    In = ParameterLocation.Query,
                    Required = true,
                    Schema = new OpenApiSchema { Type = "string" },
                    Description = "The API version"
                });
            }
        }
    }

The path parameter can then reference this global parameter via an IOperationFilter.

    public class OperationFilter : IOperationFilter
        {
            public void Apply(OpenApiOperation operation, OperationFilterContext context)
            {
                _ = operation ?? throw new ArgumentNullException(nameof(operation));
                _ = context ?? throw new ArgumentNullException(nameof(context));
    
                if (operation.Parameters == null)
                {
                    operation.Parameters = new List<OpenApiParameter>();
                }
    
                operation.Parameters.Add(
                    new OpenApiParameter
                    {
                        Reference = new OpenApiReference { Id = "parameters/api-version", ExternalResource = "" }
                    });
            }
}