Web Api How to add a Header parameter for all API in Swagger

Solution 1:

What the user "G T" wrote is correct but it is not working with Swagger 5. We have some new changes:

From: Operation to: OpenApiOperation

From: IParameter to: OpenApiParameter

From: NonBodyParameter to: OpenApiParameter, and the most important is...

From: Type = "string" to: Schema = new OpenApiSchema { Type = "String" }

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace MyAPI
{
    public class AuthorizationHeaderParameterOperationFilter: IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
            var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
            var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);

            if (isAuthorized && !allowAnonymous)
            {
                if (operation.Parameters == null)
                    operation.Parameters = new List<OpenApiParameter>();

                operation.Parameters.Add(new OpenApiParameter 
                {
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Description = "access token",
                    Required = true,
                    Schema = new OpenApiSchema
                    {
                        Type = "string",
                        Default = new OpenApiString("Bearer ")
                    }
                });
            }
        }
    }
}

And in Startup => ConfigureServices => services.AddSwaggerGen()

c.OperationFilter<AuthorizationHeaderParameterOperationFilter>();

Solution 2:

Yes you can do it via inheriting from IOperationFilter

You can find the answer on GitHub here: AddRequiredHeaderParameter

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            operation.Parameters = new List<IParameter>();

        operation.Parameters.Add(new NonBodyParameter
            {
                Name = "X-User-Token",
                In = "header",
                Type = "string",
                Required = false
            });
    }
}

Then you go to your SwaggerConfig.cs file and add the following in the AddSwaggerGen section:

c.OperationFilter<AddRequiredHeaderParameter>();

Rebuild, and enjoy.

Solution 3:

Another way to add custom headers is by adding parameters into controller action.
The following example will add x-test parameter to the UI:

[HttpPost]
public IActionResult Test([FromHeader(Name="x-test")][Required] string requiredHeader)
{
    return Ok();
}

enter image description here

Solution 4:

I have improved the respectful Wille Esteche's answer a bit. If you want to apply headers not to all methods, but only to your selected controller methods, you can use attributes.

    [HttpPost]
    [Route(nameof(Auth))]
    [SwaggerHeader(Constants.HeaderDomainSid, "Encrypted User.Sid got from client", "abc123", true)]
    public ActionResult<string> Auth([FromHeader(Name = Constants.HeaderDomainSid)] string headerDomainSid = null)
    { .....
    

Attribute class:

public class SwaggerHeaderAttribute : Attribute
{
    public string HeaderName { get; }
    public string Description { get; }
    public string DefaultValue { get; }
    public bool IsRequired { get; }

    public SwaggerHeaderAttribute(string headerName, string description = null, string defaultValue = null, bool isRequired = false)
    {
        HeaderName = headerName;
        Description = description;
        DefaultValue = defaultValue;
        IsRequired = isRequired;
    }
}

Filter:

public class SwaggerHeaderFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        operation.Parameters ??= new List<OpenApiParameter>();

        if (context.MethodInfo.GetCustomAttribute(typeof(SwaggerHeaderAttribute)) is SwaggerHeaderAttribute attribute)
        {
            var existingParam = operation.Parameters.FirstOrDefault(p =>
                p.In == ParameterLocation.Header && p.Name == attribute.HeaderName);
            if (existingParam != null) // remove description from [FromHeader] argument attribute
            {
                operation.Parameters.Remove(existingParam);
            }

            operation.Parameters.Add(new OpenApiParameter
            {
                Name = attribute.HeaderName,
                In = ParameterLocation.Header,
                Description = attribute.Description,
                Required = attribute.IsRequired,
                Schema = string.IsNullOrEmpty(attribute.DefaultValue)
                    ? null
                    : new OpenApiSchema
                    {
                        Type = "String",
                        Default = new OpenApiString(attribute.DefaultValue)
                    }
            });
        }
    }
}
    

enter image description here