Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,21 @@ private OpenApiParameter GenerateParameter(
apiParameter.RouteInfo)
: new OpenApiSchema { Type = "string" };

var description = schema.Description;
if (string.IsNullOrEmpty(description)
&& !string.IsNullOrEmpty(schema?.Reference?.Id)
&& schemaRepository.Schemas.TryGetValue(schema.Reference.Id, out var openApiSchema))
{
description = openApiSchema.Description;
}

var parameter = new OpenApiParameter
{
Name = name,
In = location,
Required = isRequired,
Schema = schema
Schema = schema,
Description = description
};

var filterContext = new ParameterFilterContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal class FakeICompositeMetadataDetailsProvider : ICompositeMetadataDetails
{
public void CreateBindingMetadata(BindingMetadataProviderContext context)
{
throw new NotImplementedException();
context.BindingMetadata.IsBindingAllowed = true;
}

public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Linq;
using System.Text;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;

namespace Swashbuckle.AspNetCore.SwaggerGen.Test.Fixtures
{
internal class TestEnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
bool isEnumArgument = (context.Type?.GenericTypeArguments?.Length ?? 0) == 1 && context.Type.GenericTypeArguments.All(b => b.IsEnum);
var isEnumArray = context.Type.IsArray && context.Type.GetElementType().IsEnum;
if (context.Type.IsEnum || isEnumArgument || isEnumArray)
{
var enumType = (context.Type.IsEnum, isEnumArgument, isEnumArray) switch
{
(true, _, _) => context.Type,
(_, true, _) => context.Type.GenericTypeArguments.First(),
_ => context.Type.GetElementType()
};
StringBuilder stringBuilder = new("<p>Members:</p><ul>");
OpenApiArray names = [];
foreach (var enumValue in Enum.GetValues(enumType))
{
if (enumValue is Enum value)
{
names.Add(new OpenApiString(value.ToString()));
stringBuilder.Append($"<li>{value} - {value:d}</li>");
}
}
schema.Extensions.Add("x-enum-varnames", names);
schema.Description = stringBuilder.Append("</ul>").ToString();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1723,15 +1723,69 @@ public void GetSwagger_Works_As_Expected_When_FromForm_Attribute_With_SwaggerIgn
Assert.Equal(new[] { nameof(SwaggerIngoreAnnotatedType.NotIgnoredString) }, mediaType.Encoding.Keys);
}

[Fact]
public void GetSwagger_Copies_Description_From_GeneratedSchema()
{
var propertyEnum = typeof(TypeWithDefaultAttributeOnEnum).GetProperty(nameof(TypeWithDefaultAttributeOnEnum.EnumWithDefault));
var modelMetadataForEnum = new DefaultModelMetadata(
new DefaultModelMetadataProvider(new FakeICompositeMetadataDetailsProvider()),
new FakeICompositeMetadataDetailsProvider(),
new DefaultMetadataDetails(ModelMetadataIdentity.ForProperty(propertyEnum, typeof(IntEnum), typeof(TypeWithDefaultAttributeOnEnum)), ModelAttributes.GetAttributesForProperty(typeof(TypeWithDefaultAttributeOnEnum), propertyEnum)));

var propertyEnumArray = typeof(TypeWithDefaultAttributeOnEnum).GetProperty(nameof(TypeWithDefaultAttributeOnEnum.EnumArrayWithDefault));
var modelMetadataForEnumArray = new DefaultModelMetadata(
new DefaultModelMetadataProvider(new FakeICompositeMetadataDetailsProvider()),
new FakeICompositeMetadataDetailsProvider(),
new DefaultMetadataDetails(ModelMetadataIdentity.ForProperty(propertyEnumArray, typeof(IntEnum[]), typeof(TypeWithDefaultAttributeOnEnum)), ModelAttributes.GetAttributesForProperty(typeof(TypeWithDefaultAttributeOnEnum), propertyEnumArray)));
var subject = Subject(
apiDescriptions:
[
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingFromFormAttributeWithSwaggerIgnore),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
parameterDescriptions: new[]
{
new ApiParameterDescription
{
Name = nameof(TypeWithDefaultAttributeOnEnum.EnumWithDefault),
Source = BindingSource.Query,
Type = typeof(IntEnum),
ModelMetadata = modelMetadataForEnum
},
new ApiParameterDescription
{
Name = nameof(TypeWithDefaultAttributeOnEnum.EnumArrayWithDefault),
Source = BindingSource.Query,
Type = typeof(IntEnum[]),
ModelMetadata = modelMetadataForEnumArray
}
})
],
schemaFilters: [new TestEnumSchemaFilter()]
);
var document = subject.GetSwagger("v1");

var operation = document.Paths["/resource"].Operations[OperationType.Post];
Assert.NotEmpty(operation.Parameters);
Assert.Equal(nameof(TypeWithDefaultAttributeOnEnum.EnumWithDefault), operation.Parameters[0].Name);
Assert.NotEmpty(operation.Parameters[0].Description);
Assert.Equal(nameof(TypeWithDefaultAttributeOnEnum.EnumArrayWithDefault), operation.Parameters[1].Name);
Assert.NotEmpty(operation.Parameters[1].Description);

}

private static SwaggerGenerator Subject(
IEnumerable<ApiDescription> apiDescriptions,
SwaggerGeneratorOptions options = null,
IEnumerable<AuthenticationScheme> authenticationSchemes = null)
IEnumerable<AuthenticationScheme> authenticationSchemes = null,
List<ISchemaFilter> schemaFilters = null)
{
return new SwaggerGenerator(
options ?? DefaultOptions,
new FakeApiDescriptionGroupCollectionProvider(apiDescriptions),
new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())),
new SchemaGenerator(new SchemaGeneratorOptions() { SchemaFilters = schemaFilters ?? [] }, new JsonSerializerDataContractResolver(new JsonSerializerOptions())),
new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty<AuthenticationScheme>())
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ public class TypeWithDefaultAttributeOnEnum
{
[DefaultValue(IntEnum.Value4)]
public IntEnum EnumWithDefault { get; set; }
[DefaultValue(new IntEnum[] { IntEnum.Value4 })]
public IntEnum[] EnumArrayWithDefault { get; set; }
}
}