Skip to content

Commit a98cb9d

Browse files
API version parameter must be explored in URL segment, even when version-neutral. Fixes #1149
1 parent c0601bf commit a98cb9d

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

src/AspNetCore/WebApi/src/Asp.Versioning.Mvc.ApiExplorer/ApiVersionParameterDescriptionContext.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ public virtual void AddParameter( string name, ApiVersionParameterLocation locat
117117
{
118118
if ( IsApiVersionNeutral && !Options.AddApiVersionParametersWhenVersionNeutral )
119119
{
120+
if ( location == Path )
121+
{
122+
UpdateUrlSegment();
123+
}
124+
120125
return;
121126
}
122127

src/AspNetCore/WebApi/test/Asp.Versioning.Mvc.ApiExplorer.Tests/ApiVersionParameterDescriptionContextTest.cs

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void add_parameter_should_add_descriptor_for_path()
8282
Name = "api-version",
8383
RouteInfo = new()
8484
{
85-
Constraints = new[] { new ApiVersionRouteConstraint() },
85+
Constraints = [new ApiVersionRouteConstraint()],
8686
},
8787
Source = BindingSource.Path,
8888
};
@@ -119,6 +119,55 @@ public void add_parameter_should_add_descriptor_for_path()
119119
o => o.ExcludingMissingMembers() );
120120
}
121121

122+
[Fact]
123+
public void add_parameter_should_add_descriptor_for_path_when_version_neutral()
124+
{
125+
// arrange
126+
var version = new ApiVersion( 1, 0 );
127+
var description = new ApiDescription()
128+
{
129+
ActionDescriptor = new ActionDescriptor() { EndpointMetadata = [ApiVersionMetadata.Neutral] },
130+
ParameterDescriptions =
131+
{
132+
new()
133+
{
134+
Name = "api-version",
135+
RouteInfo = new() { Constraints = [new ApiVersionRouteConstraint()] },
136+
Source = BindingSource.Path,
137+
},
138+
},
139+
};
140+
var modelMetadata = new Mock<ModelMetadata>( ModelMetadataIdentity.ForType( typeof( string ) ) ).Object;
141+
var options = new ApiExplorerOptions()
142+
{
143+
DefaultApiVersion = version,
144+
ApiVersionParameterSource = new UrlSegmentApiVersionReader(),
145+
};
146+
var context = new ApiVersionParameterDescriptionContext( description, version, modelMetadata, options );
147+
148+
// act
149+
context.AddParameter( "api-version", Path );
150+
151+
// assert
152+
description.ParameterDescriptions.Single().Should().BeEquivalentTo(
153+
new
154+
{
155+
Name = "api-version",
156+
ModelMetadata = modelMetadata,
157+
Source = BindingSource.Path,
158+
DefaultValue = (object) "1.0",
159+
IsRequired = true,
160+
RouteInfo = new ApiParameterRouteInfo()
161+
{
162+
DefaultValue = "1.0",
163+
IsOptional = false,
164+
Constraints = description.ParameterDescriptions[0].RouteInfo.Constraints,
165+
},
166+
Type = typeof( string ),
167+
},
168+
o => o.ExcludingMissingMembers() );
169+
}
170+
122171
[Fact]
123172
public void add_parameter_should_remove_other_descriptors_after_path_parameter_is_added()
124173
{
@@ -128,7 +177,7 @@ public void add_parameter_should_remove_other_descriptors_after_path_parameter_i
128177
Name = "api-version",
129178
RouteInfo = new()
130179
{
131-
Constraints = new[] { new ApiVersionRouteConstraint() },
180+
Constraints = [new ApiVersionRouteConstraint()],
132181
},
133182
Source = BindingSource.Path,
134183
};
@@ -179,7 +228,7 @@ public void add_parameter_should_not_add_query_parameter_after_path_parameter_ha
179228
Name = "api-version",
180229
RouteInfo = new()
181230
{
182-
Constraints = new[] { new ApiVersionRouteConstraint() },
231+
Constraints = [new ApiVersionRouteConstraint()],
183232
},
184233
Source = BindingSource.Path,
185234
};
@@ -214,7 +263,7 @@ public void add_parameter_should_add_descriptor_for_media_type_parameter()
214263
var metadata = new ApiVersionMetadata( ApiVersionModel.Empty, new ApiVersionModel( version ) );
215264
var description = new ApiDescription()
216265
{
217-
ActionDescriptor = new() { EndpointMetadata = new[] { metadata } },
266+
ActionDescriptor = new() { EndpointMetadata = [metadata] },
218267
SupportedRequestFormats = { new() { MediaType = Json } },
219268
SupportedResponseTypes = { new() { ApiResponseFormats = { new() { MediaType = Json } } } },
220269
};
@@ -304,7 +353,7 @@ public void add_parameter_should_make_parameters_optional_after_first_parameter(
304353
private static ApiDescription NewApiDescription( ApiVersion apiVersion, params ApiParameterDescription[] parameters )
305354
{
306355
var metadata = new ApiVersionMetadata( ApiVersionModel.Empty, new ApiVersionModel( apiVersion ) );
307-
var action = new ActionDescriptor() { EndpointMetadata = new[] { metadata } };
356+
var action = new ActionDescriptor() { EndpointMetadata = [metadata] };
308357
var description = new ApiDescription() { ActionDescriptor = action };
309358

310359
for ( var i = 0; i < parameters.Length; i++ )

0 commit comments

Comments
 (0)