Skip to content

Commit 9d52f61

Browse files
Merge pull request #13 from Microsoft/dev/chrimart/add-major-only-version-scheme
Implicit API Minor Version Fix
2 parents 65fdff8 + 375cef4 commit 9d52f61

File tree

5 files changed

+73
-83
lines changed

5 files changed

+73
-83
lines changed

src/Common/ApiVersion.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ private static void RequireValidStatus( string status )
139139
/// <value>The minor version number or <c>null</c>.</value>
140140
public int? MinorVersion { get; }
141141

142+
private int ImpliedMinorVersion => MinorVersion ?? 0;
143+
142144
/// <summary>
143145
/// Gets the optional version status.
144146
/// </summary>
@@ -325,8 +327,14 @@ private void AppendMajorAndMinorVersion( StringBuilder text, IFormatProvider for
325327
}
326328

327329
text.Append( MajorVersion.Value.ToString( formatProvider ) );
330+
331+
if ( MinorVersion == null )
332+
{
333+
return;
334+
}
335+
328336
text.Append( '.' );
329-
text.Append( ( MinorVersion ?? 0 ).ToString( formatProvider ) );
337+
text.Append( MinorVersion.Value.ToString( formatProvider ) );
330338
}
331339
else if ( MinorVersion != null )
332340
{
@@ -470,7 +478,7 @@ public bool Equals( ApiVersion other )
470478

471479
return Nullable.Equals( GroupVersion, other.GroupVersion ) &&
472480
Nullable.Equals( MajorVersion, other.MajorVersion ) &&
473-
Nullable.Equals( MinorVersion, other.MinorVersion ) &&
481+
ImpliedMinorVersion.Equals( other.ImpliedMinorVersion ) &&
474482
string.Equals( Status, other.Status, StringComparison.OrdinalIgnoreCase );
475483
}
476484

@@ -498,7 +506,7 @@ public virtual int CompareTo( ApiVersion other )
498506

499507
if ( result == 0 )
500508
{
501-
result = Nullable.Compare( MinorVersion, other.MinorVersion );
509+
result = ImpliedMinorVersion.CompareTo( other.ImpliedMinorVersion );
502510

503511
if ( result == 0 )
504512
{

src/Microsoft.AspNet.OData.Versioning/Web.OData/Routing/VersionedODataPathRouteConstraint.cs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ private static ApiVersion GetApiVersionFromRoutePrefix( HttpRequestMessage reque
6969
continue;
7070
}
7171

72-
requestedVersion = AddMinorVersionIfNeeded( requestedVersion );
7372
request.SetRequestedApiVersion( requestedVersion );
7473
return requestedVersion;
7574
}
@@ -86,45 +85,6 @@ private static bool TryExtractApiVersionFromSegment( string segment, out ApiVers
8685
return TryParse( text, out apiVersion );
8786
}
8887

89-
private static ApiVersion AddMinorVersionIfNeeded( ApiVersion requestedVersion )
90-
{
91-
Contract.Requires( requestedVersion != null );
92-
Contract.Ensures( Contract.Result<ApiVersion>() != null );
93-
94-
if ( requestedVersion.MinorVersion != null )
95-
{
96-
return requestedVersion;
97-
}
98-
99-
if ( requestedVersion.MajorVersion == null )
100-
{
101-
return requestedVersion;
102-
}
103-
104-
var major = requestedVersion.MajorVersion.Value;
105-
106-
if ( requestedVersion.GroupVersion == null )
107-
{
108-
if ( requestedVersion.Status == null )
109-
{
110-
return new ApiVersion( major, 0 );
111-
}
112-
else
113-
{
114-
return new ApiVersion( major, 0, requestedVersion.Status );
115-
}
116-
}
117-
118-
var group = requestedVersion.GroupVersion.Value;
119-
120-
if ( requestedVersion.Status == null )
121-
{
122-
return new ApiVersion( group, major, 0 );
123-
}
124-
125-
return new ApiVersion( group, major, 0, requestedVersion.Status );
126-
}
127-
12888
/// <summary>
12989
/// Gets the API version matched by the current OData path route constraint.
13090
/// </summary>

src/Microsoft.AspNet.WebApi.Versioning/Routing/ApiVersionRouteConstraint.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,8 @@ public bool Match( HttpRequestMessage request, IHttpRoute route, string paramete
3939
return false;
4040
}
4141

42-
requestedVersion = DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( requestedVersion );
4342
request.SetRequestedApiVersion( requestedVersion );
4443
return true;
4544
}
46-
47-
private static ApiVersion DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( ApiVersion requestedVersion )
48-
{
49-
Contract.Requires( requestedVersion != null );
50-
Contract.Ensures( Contract.Result<ApiVersion>() != null );
51-
52-
if ( requestedVersion.MajorVersion == null )
53-
{
54-
return requestedVersion;
55-
}
56-
57-
if ( requestedVersion.MinorVersion == null )
58-
{
59-
return new ApiVersion( requestedVersion.GroupVersion, requestedVersion.MajorVersion, new int?( 0 ), requestedVersion.Status );
60-
}
61-
62-
return requestedVersion;
63-
}
6445
}
6546
}

src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionRouteConstraint.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,8 @@ public bool Match( HttpContext httpContext, IRouter route, string routeKey, Rout
3737
return false;
3838
}
3939

40-
requestedVersion = DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( requestedVersion );
4140
httpContext.SetRequestedApiVersion( requestedVersion );
4241
return true;
4342
}
44-
45-
private static ApiVersion DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( ApiVersion requestedVersion )
46-
{
47-
Contract.Requires( requestedVersion != null );
48-
Contract.Ensures( Contract.Result<ApiVersion>() != null );
49-
50-
if ( requestedVersion.MajorVersion == null )
51-
{
52-
return requestedVersion;
53-
}
54-
55-
if ( requestedVersion.MinorVersion == null )
56-
{
57-
return new ApiVersion( requestedVersion.GroupVersion, requestedVersion.MajorVersion, new int?( 0 ), requestedVersion.Status );
58-
}
59-
60-
return requestedVersion;
61-
}
6243
}
6344
}

test/Microsoft.AspNet.WebApi.Versioning.Tests/ApiVersionTest.cs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,18 @@ public void is_valid_status_should_return_false_for_invalid_status( string statu
191191
[Theory]
192192
[InlineData( "2013-08-06", "2013-08-06", null, null, null )]
193193
[InlineData( "2013-08-06-Alpha", "2013-08-06", null, null, "Alpha" )]
194+
[InlineData( "1", null, 1, null, null )]
194195
[InlineData( "1.1", null, 1, 1, null )]
196+
[InlineData( "1-Alpha", null, 1, null, "Alpha" )]
195197
[InlineData( "1.1-Alpha", null, 1, 1, "Alpha" )]
198+
[InlineData( "2013-08-06.1", "2013-08-06", 1, null, null )]
196199
[InlineData( "2013-08-06.1.1", "2013-08-06", 1, 1, null )]
200+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06", 1, null, "Alpha" )]
197201
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06", 1, 1, "Alpha" )]
198202
public void parse_should_return_expected_result( string text, string groupVersionValue, int? majorVersion, int? minorVersion, string status )
199203
{
200204
// arrange
201-
var groupVersion = groupVersionValue == null ? null : new DateTime?( DateTime.Parse( groupVersionValue ) );
205+
var groupVersion = groupVersionValue == null ? null : new DateTime?( Parse( groupVersionValue ) );
202206

203207
// act
204208
var apiVersion = ApiVersion.Parse( text );
@@ -233,9 +237,13 @@ public void parse_should_throw_format_exception_for_invalid_text( string text, s
233237
[Theory]
234238
[InlineData( "2013-08-06", "2013-08-06", null, null, null )]
235239
[InlineData( "2013-08-06-Alpha", "2013-08-06", null, null, "Alpha" )]
240+
[InlineData( "1", null, 1, null, null )]
236241
[InlineData( "1.1", null, 1, 1, null )]
242+
[InlineData( "1-Alpha", null, 1, null, "Alpha" )]
237243
[InlineData( "1.1-Alpha", null, 1, 1, "Alpha" )]
244+
[InlineData( "2013-08-06.1", "2013-08-06", 1, null, null )]
238245
[InlineData( "2013-08-06.1.1", "2013-08-06", 1, 1, null )]
246+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06", 1, null, "Alpha" )]
239247
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06", 1, 1, "Alpha" )]
240248
public void try_parse_should_return_expected_api_version( string text, string groupVersionValue, int? majorVersion, int? minorVersion, string status )
241249
{
@@ -278,9 +286,12 @@ public void try_parse_should_return_false_when_text_is_invalid( string text )
278286
[Theory]
279287
[InlineData( "2013-08-06" )]
280288
[InlineData( "2013-08-06-Alpha" )]
289+
[InlineData( "1" )]
281290
[InlineData( "1.1" )]
282291
[InlineData( "1.1-Alpha" )]
292+
[InlineData( "2013-08-06.1" )]
283293
[InlineData( "2013-08-06.1.1" )]
294+
[InlineData( "2013-08-06.1-Alpha" )]
284295
[InlineData( "2013-08-06.1.1-Alpha" )]
285296
public void to_string_should_return_expected_string( string text )
286297
{
@@ -362,9 +373,13 @@ public void to_string_with_format_provider_should_throw_format_exception_when_fo
362373
[Theory]
363374
[InlineData( "2013-08-06" )]
364375
[InlineData( "2013-08-06-Alpha" )]
376+
[InlineData( "1" )]
365377
[InlineData( "1.1" )]
378+
[InlineData( "1-Alpha" )]
366379
[InlineData( "1.1-Alpha" )]
380+
[InlineData( "2013-08-06.1" )]
367381
[InlineData( "2013-08-06.1.1" )]
382+
[InlineData( "2013-08-06.1-Alpha" )]
368383
[InlineData( "2013-08-06.1.1-Alpha" )]
369384
public void equals_should_return_true_when_api_versions_are_equal( string text )
370385
{
@@ -382,9 +397,13 @@ public void equals_should_return_true_when_api_versions_are_equal( string text )
382397
[Theory]
383398
[InlineData( "2013-08-06" )]
384399
[InlineData( "2013-08-06-Alpha" )]
400+
[InlineData( "1" )]
385401
[InlineData( "1.1" )]
402+
[InlineData( "1-Alpha" )]
386403
[InlineData( "1.1-Alpha" )]
404+
[InlineData( "2013-08-06.1" )]
387405
[InlineData( "2013-08-06.1.1" )]
406+
[InlineData( "2013-08-06.1-Alpha" )]
388407
[InlineData( "2013-08-06.1.1-Alpha" )]
389408
public void equals_override_should_return_true_when_api_versions_are_equal( string text )
390409
{
@@ -402,9 +421,13 @@ public void equals_override_should_return_true_when_api_versions_are_equal( stri
402421
[Theory]
403422
[InlineData( "2013-08-06" )]
404423
[InlineData( "2013-08-06-Alpha" )]
424+
[InlineData( "1" )]
405425
[InlineData( "1.1" )]
426+
[InlineData( "1-Alpha" )]
406427
[InlineData( "1.1-Alpha" )]
428+
[InlineData( "2013-08-06.1" )]
407429
[InlineData( "2013-08-06.1.1" )]
430+
[InlineData( "2013-08-06.1-Alpha" )]
408431
[InlineData( "2013-08-06.1.1-Alpha" )]
409432
public void X3DX3D_should_return_true_when_api_versions_are_equal( string text )
410433
{
@@ -448,7 +471,7 @@ public void equals_override_should_return_false_when_api_versions_are_not_equal(
448471
}
449472

450473
[Fact]
451-
public void X21X3D_should_return_true_when_api_versions_are_not_equal()
474+
public void ne_should_return_true_when_api_versions_are_not_equal()
452475
{
453476
// arrange
454477
var v1 = new ApiVersion( Today );
@@ -468,12 +491,17 @@ public void X21X3D_should_return_true_when_api_versions_are_not_equal()
468491
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", 0 )]
469492
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", 1 )]
470493
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", -1 )]
494+
[InlineData( "1", "1", 0 )]
495+
[InlineData( "1", "1.0", 0 )]
471496
[InlineData( "1.1", "1.1", 0 )]
472497
[InlineData( "2.0", "1.1", 1 )]
473498
[InlineData( "1.1", "2.0", -1 )]
499+
[InlineData( "1-Alpha", "1-Alpha", 0 )]
500+
[InlineData( "1-Alpha", "1.0-Alpha", 0 )]
474501
[InlineData( "1.1-Alpha", "1.1-Alpha", 0 )]
475502
[InlineData( "1.1-Beta", "1.1-Alpha", 1 )]
476503
[InlineData( "1.1-Alpha", "1.1-Beta", -1 )]
504+
[InlineData( "2013-08-06.1", "2013-08-06.1.0", 0 )]
477505
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", 0 )]
478506
[InlineData( "2013-08-06.2", "2013-08-06.1.1", 1 )]
479507
[InlineData( "2013-08-06.1", "2013-08-06.1.1", -1 )]
@@ -502,15 +530,23 @@ public void api_version_comparisons_should_return_expected_result( string versio
502530
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", false )]
503531
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", false )]
504532
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", true )]
533+
[InlineData( "1", "1", false )]
534+
[InlineData( "1", "1.0", false )]
505535
[InlineData( "1.1", "1.1", false )]
506536
[InlineData( "2.0", "1.1", false )]
507537
[InlineData( "1.1", "2.0", true )]
538+
[InlineData( "1-Alpha", "1-Alpha", false )]
539+
[InlineData( "1-Alpha", "1.0-Alpha", false )]
508540
[InlineData( "1.1-Alpha", "1.1-Alpha", false )]
509541
[InlineData( "1.1-Beta", "1.1-Alpha", false )]
510542
[InlineData( "1.1-Alpha", "1.1-Beta", true )]
543+
[InlineData( "2013-08-06.1", "2013-08-06.1", false )]
544+
[InlineData( "2013-08-06.1", "2013-08-06.1.0", false )]
511545
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", false )]
512546
[InlineData( "2013-08-06.2", "2013-08-06.1.1", false )]
513547
[InlineData( "2013-08-06.1", "2013-08-06.1.1", true )]
548+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", false )]
549+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", false )]
514550
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", false )]
515551
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", false )]
516552
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", true )]
@@ -538,15 +574,23 @@ public void api_version_1_lt_api_version_2_should_return_expected_result( string
538574
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", true )]
539575
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", false )]
540576
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", true )]
577+
[InlineData( "1", "1", true )]
578+
[InlineData( "1", "1.0", true )]
541579
[InlineData( "1.1", "1.1", true )]
542580
[InlineData( "2.0", "1.1", false )]
543581
[InlineData( "1.1", "2.0", true )]
582+
[InlineData( "1-Alpha", "1-Alpha", true )]
583+
[InlineData( "1-Alpha", "1.0-Alpha", true )]
544584
[InlineData( "1.1-Alpha", "1.1-Alpha", true )]
545585
[InlineData( "1.1-Beta", "1.1-Alpha", false )]
546586
[InlineData( "1.1-Alpha", "1.1-Beta", true )]
587+
[InlineData( "2013-08-06.1", "2013-08-06.1", true )]
588+
[InlineData( "2013-08-06.1", "2013-08-06.1.0", true )]
547589
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", true )]
548590
[InlineData( "2013-08-06.2", "2013-08-06.1.1", false )]
549591
[InlineData( "2013-08-06.1", "2013-08-06.1.1", true )]
592+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", true )]
593+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", true )]
550594
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", true )]
551595
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", false )]
552596
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", true )]
@@ -574,15 +618,23 @@ public void api_version_1_le_api_version_2_should_return_expected_result( string
574618
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", false )]
575619
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", true )]
576620
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", false )]
621+
[InlineData( "1", "1", false )]
622+
[InlineData( "1", "1.0", false )]
577623
[InlineData( "1.1", "1.1", false )]
578624
[InlineData( "2.0", "1.1", true )]
579625
[InlineData( "1.1", "2.0", false )]
626+
[InlineData( "1-Alpha", "1-Alpha", false )]
627+
[InlineData( "1-Alpha", "1.0-Alpha", false )]
580628
[InlineData( "1.1-Alpha", "1.1-Alpha", false )]
581629
[InlineData( "1.1-Beta", "1.1-Alpha", true )]
582630
[InlineData( "1.1-Alpha", "1.1-Beta", false )]
631+
[InlineData( "2013-08-06.1", "2013-08-06.1", false )]
632+
[InlineData( "2013-08-06.1", "2013-08-06.1.0", false )]
583633
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", false )]
584634
[InlineData( "2013-08-06.2", "2013-08-06.1.1", true )]
585635
[InlineData( "2013-08-06.1", "2013-08-06.1.1", false )]
636+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", false )]
637+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", false )]
586638
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", false )]
587639
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", true )]
588640
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", false )]
@@ -610,15 +662,23 @@ public void api_version_1_gt_api_version_2_should_return_expected_result( string
610662
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", true )]
611663
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", true )]
612664
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", false )]
665+
[InlineData( "1", "1", true )]
666+
[InlineData( "1", "1.0", true )]
613667
[InlineData( "1.1", "1.1", true )]
614668
[InlineData( "2.0", "1.1", true )]
615669
[InlineData( "1.1", "2.0", false )]
670+
[InlineData( "1-Alpha", "1-Alpha", true )]
671+
[InlineData( "1-Alpha", "1.0-Alpha", true )]
616672
[InlineData( "1.1-Alpha", "1.1-Alpha", true )]
617673
[InlineData( "1.1-Beta", "1.1-Alpha", true )]
618674
[InlineData( "1.1-Alpha", "1.1-Beta", false )]
675+
[InlineData( "2013-08-06.1", "2013-08-06.1", true )]
676+
[InlineData( "2013-08-06.1", "2013-08-06.1.0", true )]
619677
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", true )]
620678
[InlineData( "2013-08-06.2", "2013-08-06.1.1", true )]
621679
[InlineData( "2013-08-06.1", "2013-08-06.1.1", false )]
680+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", true )]
681+
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", true )]
622682
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", true )]
623683
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", true )]
624684
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", false )]

0 commit comments

Comments
 (0)