Skip to content

Commit 832c45a

Browse files
[OpenAPI] Get default value with [FromQuery]
Get the default value from the associated object's property when `[FromQuery]` is applied to a property of an object used as a `[FromQuery]` parameter. Resolves #61934.
1 parent 3ade4fb commit 832c45a

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

src/OpenApi/src/Extensions/JsonNodeSchemaExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ internal static void ApplyParameterInfo(this JsonNode schema, ApiParameterDescri
309309
var attributes = validations.OfType<ValidationAttribute>();
310310
schema.ApplyValidationAttributes(attributes);
311311
}
312+
if (parameterDescription.ModelMetadata is Mvc.ModelBinding.Metadata.DefaultModelMetadata { Attributes.PropertyAttributes.Count: > 0 } metadata &&
313+
metadata.Attributes.PropertyAttributes.OfType<DefaultValueAttribute>().LastOrDefault() is { } metadataDefaultValueAttribute)
314+
{
315+
schema.ApplyDefaultValue(metadataDefaultValueAttribute.Value, jsonTypeInfo);
316+
}
312317
if (parameterDescription.ParameterDescriptor is IParameterInfoParameterDescriptor { ParameterInfo: { } parameterInfo })
313318
{
314319
if (parameterInfo.HasDefaultValue)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,7 @@ public async Task GetOpenApiParameters_HandlesAsParametersParametersWithDescript
522522
await VerifyOpenApiDocument(builder, document =>
523523
{
524524
var operation = document.Paths["/api"].Operations[HttpMethod.Get];
525-
var parameter = Assert.Single(operation.Parameters);
526-
Assert.Equal("The ID of the entity", parameter.Description);
525+
Assert.Contains(operation.Parameters, actualMemory => actualMemory.Name == "id" && actualMemory.Description == "The ID of the entity");
527526
});
528527
}
529528

@@ -537,8 +536,56 @@ public async Task GetOpenApiParameters_HandlesFromQueryParametersWithDescription
537536
await VerifyOpenApiDocument(actionDescriptor, document =>
538537
{
539538
var operation = document.Paths["/"].Operations[HttpMethod.Get];
540-
var parameter = Assert.Single(operation.Parameters);
541-
Assert.Equal("The ID of the entity", parameter.Description);
539+
Assert.Contains(operation.Parameters, actualMemory => actualMemory.Name == "id" && actualMemory.Description == "The ID of the entity");
540+
});
541+
}
542+
543+
[Fact]
544+
public async Task GetOpenApiParameters_HandlesAsParametersParametersWithDefaultValueAttribute()
545+
{
546+
// Arrange
547+
var builder = CreateBuilder();
548+
549+
// Act
550+
builder.MapGet("/api", ([AsParameters] FromQueryModel model) => { });
551+
552+
// Assert
553+
await VerifyOpenApiDocument(builder, document =>
554+
{
555+
var operation = document.Paths["/api"].Operations[HttpMethod.Get];
556+
Assert.Contains(
557+
operation.Parameters,
558+
actualMemory =>
559+
{
560+
return actualMemory.Name == "limit" &&
561+
actualMemory.Schema != null &&
562+
actualMemory.Schema.Default != null &&
563+
actualMemory.Schema.Default.GetValueKind() == JsonValueKind.Number &&
564+
actualMemory.Schema.Default.GetValue<int>() == 20;
565+
});
566+
});
567+
}
568+
569+
[Fact]
570+
public async Task GetOpenApiParameters_HandlesFromQueryParametersWithDefaultValueAttribute()
571+
{
572+
// Arrange
573+
var actionDescriptor = CreateActionDescriptor(nameof(TestFromQueryController.GetWithFromQueryDto), typeof(TestFromQueryController));
574+
575+
// Assert
576+
await VerifyOpenApiDocument(actionDescriptor, document =>
577+
{
578+
var operation = document.Paths["/"].Operations[HttpMethod.Get];
579+
Assert.Contains(
580+
operation.Parameters,
581+
actualMemory =>
582+
{
583+
return actualMemory.Name == "limit" &&
584+
actualMemory.Schema != null &&
585+
actualMemory.Schema.Default != null &&
586+
actualMemory.Schema.Default.GetValueKind() == JsonValueKind.Number &&
587+
actualMemory.Schema.Default.GetValue<int>() == 20;
588+
});
542589
});
543590
}
544591

@@ -860,5 +907,10 @@ private record FromQueryModel
860907
[Description("The ID of the entity")]
861908
[FromQuery(Name = "id")]
862909
public int Id { get; set; }
910+
911+
[Description("The maximum number of results")]
912+
[FromQuery(Name = "limit")]
913+
[DefaultValue(20)]
914+
public int Limit { get; set; }
863915
}
864916
}

0 commit comments

Comments
 (0)