Merge pull request #885 from dotnet-maestro-bot/merge/release/2.2-to-master

[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
James Newton-King 2018-10-23 09:18:17 +13:00 committed by GitHub
commit bc140fc491
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 34 deletions

View File

@ -85,6 +85,10 @@ namespace Microsoft.AspNetCore.Routing.Patterns
if (IsCatchAll) if (IsCatchAll)
{ {
builder.Append("*"); builder.Append("*");
if (!EncodeSlashes)
{
builder.Append("*");
}
} }
builder.Append(Name); builder.Append(Name);

View File

@ -89,17 +89,6 @@ namespace Microsoft.AspNetCore.Routing.Template
_defaults = defaults; _defaults = defaults;
_requiredKeys = requiredKeys?.ToArray() ?? Array.Empty<string>(); _requiredKeys = requiredKeys?.ToArray() ?? Array.Empty<string>();
for (var i = 0; i < _requiredKeys.Length; i++)
{
var requiredKey = _requiredKeys[i];
if (_pattern.GetParameter(requiredKey) != null)
{
throw new InvalidOperationException(
$"The parameter {requiredKey} can not be used as a required key since it appears as " +
$"a parameter in the route pattern.");
}
}
// Any default that doesn't have a corresponding parameter is a 'filter' and if a value // Any default that doesn't have a corresponding parameter is a 'filter' and if a value
// is provided for that 'filter' it must match the value in defaults. // is provided for that 'filter' it must match the value in defaults.
var filters = new RouteValueDictionary(_defaults); var filters = new RouteValueDictionary(_defaults);

View File

@ -441,9 +441,9 @@ namespace Microsoft.AspNetCore.Routing
// Act // Act
var uri = linkGenerator.GetPathByAddress( var uri = linkGenerator.GetPathByAddress(
httpContext, httpContext,
1, 1,
values: new RouteValueDictionary(new { action = "Index", }), values: new RouteValueDictionary(new { action = "Index", }),
ambientValues: new RouteValueDictionary(new { controller = "Home", })); ambientValues: new RouteValueDictionary(new { controller = "Home", }));
// Assert // Assert
@ -465,8 +465,8 @@ namespace Microsoft.AspNetCore.Routing
// Act // Act
var uri = linkGenerator.GetUriByAddress( var uri = linkGenerator.GetUriByAddress(
httpContext, httpContext,
1, 1,
values: new RouteValueDictionary(new { action = "Index", }), values: new RouteValueDictionary(new { action = "Index", }),
ambientValues: new RouteValueDictionary(new { controller = "Home", })); ambientValues: new RouteValueDictionary(new { controller = "Home", }));
@ -490,7 +490,7 @@ namespace Microsoft.AspNetCore.Routing
var uri = linkGenerator.GetPathByAddress( var uri = linkGenerator.GetPathByAddress(
httpContext, httpContext,
1, 1,
values: new RouteValueDictionary(new { action = "Index", controller= "Home", }), values: new RouteValueDictionary(new { action = "Index", controller = "Home", }),
pathBase: "/"); pathBase: "/");
// Assert // Assert
@ -598,8 +598,11 @@ namespace Microsoft.AspNetCore.Routing
Assert.NotSame(original, actual); Assert.NotSame(original, actual);
} }
[Fact] [Theory]
public void GetPathByRouteValues_UsesFirstTemplateThatSucceeds() [InlineData(new string[] { }, new string[] { }, "/")]
[InlineData(new string[] { "id" }, new string[] { "3" }, "/Home/Index/3")]
[InlineData(new string[] { "custom" }, new string[] { "Custom" }, "/?custom=Custom")]
public void GetPathByRouteValues_UsesFirstTemplateThatSucceeds(string[] routeNames, string[] routeValues, string expectedPath)
{ {
// Arrange // Arrange
var endpointControllerAction = EndpointFactory.CreateRouteEndpoint( var endpointControllerAction = EndpointFactory.CreateRouteEndpoint(
@ -634,26 +637,103 @@ namespace Microsoft.AspNetCore.Routing
var httpContext = CreateHttpContext(); var httpContext = CreateHttpContext();
httpContext.Features.Set<IRouteValuesFeature>(context); httpContext.Features.Set<IRouteValuesFeature>(context);
var values = new RouteValueDictionary();
for (int i = 0; i < routeNames.Length; i++)
{
values[routeNames[i]] = routeValues[i];
}
// Act // Act
var pathWithoutId = linkGenerator.GetPathByRouteValues( var generatedPath = linkGenerator.GetPathByRouteValues(
httpContext, httpContext,
routeName: null, routeName: null,
values: new RouteValueDictionary()); values: values);
var pathWithId = linkGenerator.GetPathByRouteValues(
httpContext,
routeName: null,
values: new RouteValueDictionary(new { id = "3" }));
var pathWithCustom = linkGenerator.GetPathByRouteValues(
httpContext,
routeName: null,
values: new RouteValueDictionary(new { custom = "Custom" }));
// Assert // Assert
Assert.Equal("/", pathWithoutId); Assert.Equal(expectedPath, generatedPath);
Assert.Equal("/Home/Index/3", pathWithId); }
Assert.Equal("/?custom=Custom", pathWithCustom);
[Theory]
[InlineData(new string[] { }, new string[] { }, "/")]
[InlineData(new string[] { "id" }, new string[] { "3" }, "/Home/Index/3")]
[InlineData(new string[] { "custom" }, new string[] { "Custom" }, "/?custom=Custom")]
[InlineData(new string[] { "controller", "action", "id" }, new string[] { "Home", "Login", "3" }, "/Home/Login/3")]
[InlineData(new string[] { "controller", "action", "id" }, new string[] { "Home", "Fake", "3" }, null)]
public void GetPathByRouteValues_ParameterMatchesRequireValues_HasAmbientValues(string[] routeNames, string[] routeValues, string expectedPath)
{
// Arrange
var homeIndex = EndpointFactory.CreateRouteEndpoint(
"{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index", },
metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
var homeLogin = EndpointFactory.CreateRouteEndpoint(
"{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index", },
metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Login", })) });
var linkGenerator = CreateLinkGenerator(homeIndex, homeLogin);
var context = new EndpointSelectorContext()
{
RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index", })
};
var httpContext = CreateHttpContext();
httpContext.Features.Set<IRouteValuesFeature>(context);
var values = new RouteValueDictionary();
for (int i = 0; i < routeNames.Length; i++)
{
values[routeNames[i]] = routeValues[i];
}
// Act
var generatedPath = linkGenerator.GetPathByRouteValues(
httpContext,
routeName: null,
values: values);
// Assert
Assert.Equal(expectedPath, generatedPath);
}
[Theory]
[InlineData(new string[] { }, new string[] { }, null)]
[InlineData(new string[] { "id" }, new string[] { "3" }, null)]
[InlineData(new string[] { "custom" }, new string[] { "Custom" }, null)]
[InlineData(new string[] { "controller", "action", "id" }, new string[] { "Home", "Login", "3" }, "/Home/Login/3")]
[InlineData(new string[] { "controller", "action", "id" }, new string[] { "Home", "Fake", "3" }, null)]
public void GetPathByRouteValues_ParameterMatchesRequireValues_NoAmbientValues(string[] routeNames, string[] routeValues, string expectedPath)
{
// Arrange
var homeIndex = EndpointFactory.CreateRouteEndpoint(
"{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index", },
metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
var homeLogin = EndpointFactory.CreateRouteEndpoint(
"{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index", },
metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Login", })) });
var linkGenerator = CreateLinkGenerator(homeIndex, homeLogin);
var context = new EndpointSelectorContext();
var httpContext = CreateHttpContext();
httpContext.Features.Set<IRouteValuesFeature>(context);
var values = new RouteValueDictionary();
for (int i = 0; i < routeNames.Length; i++)
{
values[routeNames[i]] = routeValues[i];
}
// Act
var generatedPath = linkGenerator.GetPathByRouteValues(
httpContext,
routeName: null,
values: values);
// Assert
Assert.Equal(expectedPath, generatedPath);
} }
protected override void AddAdditionalServices(IServiceCollection services) protected override void AddAdditionalServices(IServiceCollection services)