Add default value to Swagger path parameters

Viewed 1312

I have made a WebAPI in .NET CORE 6.

I have a controller class like this:

    [ApiController]
    [Route("{culture:culture}/[controller]")]
    [SwaggerDefaultValue("culture", "en-US")]
    [Produces("application/json")]
    public class AccountsController : BaseController
    {
         ...
    }

As you can see I defined a parameter in the route like this {culture:culture}.

I would like to have a default value for this parameter in my Swagger.

I defined an attribute class like this:

    [AttributeUsage(AttributeTargets.Class )]
    public class SwaggerDefaultValueAttribute:Attribute
    {
        public string Name { get; set; }
        public string Value { get; set; }

        public SwaggerDefaultValueAttribute(string name, string value)
        {
            Name = name;
            Value = value;
        }
    }

And a filter class like this:

    public class SwaggerDefaultValueFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
           // needs some code
        }
    }

And added the filter to my Swagger service too.

options.OperationFilter<SwaggerDefaultValueFilter>();

However, the problem is most of the code samples that I found are related to the old versions of Swagger and most of their methods are deprecated (like this one).

The question is, how can I modify this SwaggerDefaultValueFilter class to show a default value in my path parameter:

enter image description here

FYI: I am using <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.2.3" />.

I found this sample too, however, it does not set the default values of the path parameters, it seems it works for model attributes.

2 Answers

To assign the default value for the parameter, you can do something like this,

internal static class OperationFilterContextExtensions
{
    public static IEnumerable<T> GetControllerAndActionAttributes<T>(this OperationFilterContext context) where T : Attribute
    {
        var controllerAttributes = context.MethodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes<T>();
        var actionAttributes = context.MethodInfo.GetCustomAttributes<T>();

        var result = new List<T>(controllerAttributes);
        result.AddRange(actionAttributes);
        return result;
    }
}

public class SwaggerDefaultValueFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {

        var defaultAttributes = context.GetControllerAndActionAttributes<SwaggerDefaultValueAttribute>();

        if (defaultAttributes.Any())
        {
            foreach (var defaultAttribute in defaultAttributes)
            {
                var parameter = operation.Parameters.FirstOrDefault(d => d.Name == defaultAttribute.Name);
                if (parameter != null)
                {
                    version.Schema.Default = new OpenApiString(defaultAttribute.Value);
                }
            }
        }
    }
}

Not Swashbuckle.AspNetCore but this might send you on the right path:

Controller:
https://github.com/heldersepu/Swagger-Net-Test/blob/master/Swagger_Test/Controllers/CompanyController.cs#L35-L39

        [Route("Get2")]
        public Company Get2([FromUri] Company c)
        {
            return c;
        }

Model:
https://github.com/heldersepu/Swagger-Net-Test/blob/master/Swagger_Test/Models/Company.cs

    public class Company
    {
        /// <summary>The Unique Company ID</summary>
        /// <example>123</example>
        [Required]
        [DefaultValue(456)]
        public int Id { get; set; }

        [Required]
        [DefaultValue(null)]
        public int? MyId { get; set; }

        /// <summary>The Company Name</summary>
        /// <example>Acme co</example>
        [DefaultValue("My Company")]
        public string Name { get; set; }

Live code:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=Company#/Company/Company_Get2

Related