Skip to content

Commit 4892d78

Browse files
Chris Martinezcommonsensesoftware
Chris Martinez
authored andcommitted
Correct MVC routing and add more acceptance tests. Fixes #130
1 parent 9f16e38 commit 4892d78

File tree

9 files changed

+122
-6
lines changed

9 files changed

+122
-6
lines changed

ApiVersioningWithSamples.sln

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26403.7
4+
VisualStudioVersion = 15.0.26430.6
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D5F5F21-0CB7-4B4E-A42F-732BD4AFD0FF}"
77
EndProject

src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersionActionSelector.cs

+23-2
Original file line numberDiff line numberDiff line change
@@ -382,18 +382,39 @@ internal MatchingActionSequence( IReadOnlyList<ActionDescriptor> matches, RouteD
382382

383383
internal ActionDescriptorMatch BestMatch { get; private set; }
384384

385+
RouteData NewMatchRouteData( ActionDescriptor match )
386+
{
387+
Contract.Requires( match != null );
388+
Contract.Ensures( Contract.Result<RouteData>() != null );
389+
390+
var matchedRouteData = new RouteData( routeData );
391+
var matchedRouteValues = matchedRouteData.Values;
392+
393+
foreach ( var entry in match.RouteValues )
394+
{
395+
if ( !matchedRouteValues.ContainsKey( entry.Key ) )
396+
{
397+
matchedRouteValues.Add( entry.Key, entry.Value );
398+
}
399+
}
400+
401+
return matchedRouteData;
402+
}
403+
385404
public IEnumerator<ActionDescriptorMatch> GetEnumerator()
386405
{
387406
if ( matches.Count == 1 )
388407
{
389-
BestMatch = new ActionDescriptorMatch( matches[0], routeData );
408+
var match = matches[0];
409+
BestMatch = new ActionDescriptorMatch( match, NewMatchRouteData( match ) );
390410
yield return BestMatch;
391411
}
392412
else
393413
{
394414
for ( var i = 0; i < matches.Count; i++ )
395415
{
396-
yield return new ActionDescriptorMatch( matches[i], routeData );
416+
var match = matches[i];
417+
yield return new ActionDescriptorMatch( match, NewMatchRouteData( match ) );
397418
}
398419
}
399420
}

test/Microsoft.AspNetCore.Mvc.Acceptance.Tests/Basic/BasicAcceptanceTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ protected BasicAcceptanceTest()
1212
FilteredControllerTypes.Add( typeof( Values2Controller ).GetTypeInfo() );
1313
FilteredControllerTypes.Add( typeof( HelloWorldController ).GetTypeInfo() );
1414
FilteredControllerTypes.Add( typeof( HelloWorld2Controller ).GetTypeInfo() );
15-
FilteredControllerTypes.Add( typeof( HomeController ).GetTypeInfo() );
15+
FilteredControllerTypes.Add( typeof( PingController ).GetTypeInfo() );
1616
}
1717

1818
protected override void OnAddApiVersioning( ApiVersioningOptions options ) => options.ReportApiVersions = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Microsoft.AspNetCore.Mvc.Basic.Controllers
2+
{
3+
using System;
4+
5+
[ApiVersionNeutral]
6+
[Route( "api/[controller]" )]
7+
public class PingController : Controller
8+
{
9+
[HttpGet]
10+
public IActionResult Get() => NoContent();
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace Microsoft.AspNetCore.Mvc.Basic.Controllers.WithViewsUsingAttributes
2+
{
3+
using System;
4+
5+
[ApiVersionNeutral]
6+
[Route( "" )]
7+
[Route( "[controller]" )]
8+
public class HomeController : Controller
9+
{
10+
[HttpGet( "" )]
11+
[HttpGet( nameof( Index ) )]
12+
public IActionResult Index() => View();
13+
}
14+
}

test/Microsoft.AspNetCore.Mvc.Acceptance.Tests/Basic/Controllers/HomeController.cs renamed to test/Microsoft.AspNetCore.Mvc.Acceptance.Tests/Basic/Controllers/WithViewsUsingConventions/HomeController.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Microsoft.AspNetCore.Mvc.Basic.Controllers
1+
namespace Microsoft.AspNetCore.Mvc.Basic.Controllers.WithViewsUsingConventions
22
{
33
using System;
44

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace given_a_versionX2Dneutral_Controller
2+
{
3+
using FluentAssertions;
4+
using Microsoft.AspNetCore.Mvc.Basic;
5+
using System.Threading.Tasks;
6+
using Xunit;
7+
using static System.Net.HttpStatusCode;
8+
9+
public class when_no_version_is_specified : BasicAcceptanceTest
10+
{
11+
[Fact]
12+
public async Task then_get_should_return_204()
13+
{
14+
// arrange
15+
16+
17+
// act
18+
var response = await GetAsync( "api/ping" );
19+
20+
// assert
21+
response.StatusCode.Should().Be( NoContent );
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace given_a_versionX2Dneutral_UI_Controller
2+
{
3+
using FluentAssertions;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.AspNetCore.Mvc.Basic;
6+
using Microsoft.AspNetCore.Mvc.Basic.Controllers.WithViewsUsingAttributes;
7+
using System.Net.Http.Headers;
8+
using System.Reflection;
9+
using System.Threading.Tasks;
10+
using Xunit;
11+
12+
public class when_accessing_a_view_using_attribute_routing : BasicAcceptanceTest
13+
{
14+
public when_accessing_a_view_using_attribute_routing()
15+
{
16+
FilteredControllerTypes.Clear();
17+
FilteredControllerTypes.Add( typeof( HomeController ).GetTypeInfo() );
18+
}
19+
20+
[Theory]
21+
[InlineData( "http://localhost" )]
22+
[InlineData( "http://localhost/home" )]
23+
[InlineData( "http://localhost/home/index" )]
24+
[InlineData( "http://localhost/index" )]
25+
public async Task then_get_should_return_200( string requestUrl )
26+
{
27+
// arrange
28+
Client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue( "text/html" ) );
29+
30+
// act
31+
var response = await GetAsync( requestUrl ).EnsureSuccessStatusCode();
32+
33+
// assert
34+
response.Content.Headers.ContentType.MediaType.Should().Be( "text/html" );
35+
}
36+
}
37+
}

test/Microsoft.AspNetCore.Mvc.Acceptance.Tests/Basic/given a version-neutral UI Controller/when accessing a view.cs renamed to test/Microsoft.AspNetCore.Mvc.Acceptance.Tests/Basic/given a version-neutral UI Controller/when accessing a view using convention routing.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,20 @@
33
using FluentAssertions;
44
using Microsoft.AspNetCore.Mvc;
55
using Microsoft.AspNetCore.Mvc.Basic;
6+
using Microsoft.AspNetCore.Mvc.Basic.Controllers.WithViewsUsingConventions;
67
using System.Net.Http.Headers;
8+
using System.Reflection;
79
using System.Threading.Tasks;
810
using Xunit;
911

10-
public class when_accessing_a_view : BasicAcceptanceTest
12+
public class when_accessing_a_view_using_convention_routing : BasicAcceptanceTest
1113
{
14+
public when_accessing_a_view_using_convention_routing()
15+
{
16+
FilteredControllerTypes.Clear();
17+
FilteredControllerTypes.Add( typeof( HomeController ).GetTypeInfo() );
18+
}
19+
1220
[Theory]
1321
[InlineData( "http://localhost" )]
1422
[InlineData( "http://localhost/home" )]

0 commit comments

Comments
 (0)