Merge branch 'rel/2.0.0-preview1' into dev
This commit is contained in:
commit
57714b45f3
|
|
@ -64,6 +64,9 @@ namespace Microsoft.AspNetCore.Routing.Template
|
||||||
// If the URI had ordered parameters a="1", b="2", c="3" and the new values
|
// If the URI had ordered parameters a="1", b="2", c="3" and the new values
|
||||||
// specified that b="9", then we need to invalidate everything after it. The new
|
// specified that b="9", then we need to invalidate everything after it. The new
|
||||||
// values should then be a="1", b="9", c=<no value>.
|
// values should then be a="1", b="9", c=<no value>.
|
||||||
|
//
|
||||||
|
// We also handle the case where a parameter is optional but has no value - we shouldn't
|
||||||
|
// accept additional parameters that appear *after* that parameter.
|
||||||
for (var i = 0; i < _template.Parameters.Count; i++)
|
for (var i = 0; i < _template.Parameters.Count; i++)
|
||||||
{
|
{
|
||||||
var parameter = _template.Parameters[i];
|
var parameter = _template.Parameters[i];
|
||||||
|
|
@ -87,6 +90,25 @@ namespace Microsoft.AspNetCore.Routing.Template
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasNewParameterValue &&
|
||||||
|
!hasCurrentParameterValue &&
|
||||||
|
_defaults?.ContainsKey(parameter.Name) != true)
|
||||||
|
{
|
||||||
|
// This is an unsatisfied parameter value and there are no defaults. We might still
|
||||||
|
// be able to generate a URL but we should stop 'accepting' ambient values.
|
||||||
|
//
|
||||||
|
// This might be a case like:
|
||||||
|
// template: a/{b?}/{c?}
|
||||||
|
// ambient: { c = 17 }
|
||||||
|
// values: { }
|
||||||
|
//
|
||||||
|
// We can still generate a URL from this ("/a") but we shouldn't accept 'c' because
|
||||||
|
// we can't use it.
|
||||||
|
//
|
||||||
|
// In the example above we should fall into this block for 'b'.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// If the parameter is a match, add it to the list of values we will use for URI generation
|
// If the parameter is a match, add it to the list of values we will use for URI generation
|
||||||
if (hasNewParameterValue)
|
if (hasNewParameterValue)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1372,6 +1372,103 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
Assert.Empty(pathData.DataTokens);
|
Assert.Empty(pathData.DataTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetVirtualPath_TwoOptionalParameters_OneValueFromAmbientValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var route = CreateRoute(
|
||||||
|
template: "a/{b=15}/{c?}/{d?}",
|
||||||
|
defaults: null,
|
||||||
|
handleRequest: true,
|
||||||
|
constraints: null);
|
||||||
|
|
||||||
|
var context = CreateVirtualPathContext(
|
||||||
|
values: new { },
|
||||||
|
ambientValues: new { c = "17" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pathData = route.GetVirtualPath(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(pathData);
|
||||||
|
Assert.Equal("/a/15/17", pathData.VirtualPath);
|
||||||
|
Assert.Same(route, pathData.Router);
|
||||||
|
Assert.Empty(pathData.DataTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetVirtualPath_OptionalParameterAfterDefault_OneValueFromAmbientValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var route = CreateRoute(
|
||||||
|
template: "a/{b=15}/{c?}",
|
||||||
|
defaults: null,
|
||||||
|
handleRequest: true,
|
||||||
|
constraints: null);
|
||||||
|
|
||||||
|
var context = CreateVirtualPathContext(
|
||||||
|
values: new { },
|
||||||
|
ambientValues: new { c = "17" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pathData = route.GetVirtualPath(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(pathData);
|
||||||
|
Assert.Equal("/a/15/17", pathData.VirtualPath);
|
||||||
|
Assert.Same(route, pathData.Router);
|
||||||
|
Assert.Empty(pathData.DataTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetVirtualPath_TwoOptionalParametersAfterDefault_OneValueFromAmbientValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var route = CreateRoute(
|
||||||
|
template: "a/{b=15}/{c?}/{d?}",
|
||||||
|
defaults: null,
|
||||||
|
handleRequest: true,
|
||||||
|
constraints: null);
|
||||||
|
|
||||||
|
var context = CreateVirtualPathContext(
|
||||||
|
values: new { },
|
||||||
|
ambientValues: new { c = "17" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pathData = route.GetVirtualPath(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(pathData);
|
||||||
|
Assert.Equal("/a/15/17", pathData.VirtualPath);
|
||||||
|
Assert.Same(route, pathData.Router);
|
||||||
|
Assert.Empty(pathData.DataTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetVirtualPath_TwoOptionalParametersAfterDefault_LastValueFromAmbientValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var route = CreateRoute(
|
||||||
|
template: "a/{b=15}/{c?}/{d?}",
|
||||||
|
defaults: null,
|
||||||
|
handleRequest: true,
|
||||||
|
constraints: null);
|
||||||
|
|
||||||
|
var context = CreateVirtualPathContext(
|
||||||
|
values: new { },
|
||||||
|
ambientValues: new { d = "17" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pathData = route.GetVirtualPath(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(pathData);
|
||||||
|
Assert.Equal("/a", pathData.VirtualPath);
|
||||||
|
Assert.Same(route, pathData.Router);
|
||||||
|
Assert.Empty(pathData.DataTokens);
|
||||||
|
}
|
||||||
|
|
||||||
private static VirtualPathContext CreateVirtualPathContext(object values)
|
private static VirtualPathContext CreateVirtualPathContext(object values)
|
||||||
{
|
{
|
||||||
return CreateVirtualPathContext(new RouteValueDictionary(values), null);
|
return CreateVirtualPathContext(new RouteValueDictionary(values), null);
|
||||||
|
|
|
||||||
|
|
@ -1317,6 +1317,27 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
Assert.Empty(pathData.DataTokens);
|
Assert.Empty(pathData.DataTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TreeRouter_GenerateLink_Match_HasTwoOptionalParametersWithoutValues()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var builder = CreateBuilder();
|
||||||
|
MapOutboundEntry(builder, "Customers/SeparatePageModels/{handler?}/{id?}", new { page = "/Customers/SeparatePageModels/Index" });
|
||||||
|
var route = builder.Build();
|
||||||
|
|
||||||
|
var context = CreateVirtualPathContext(new { page = "/Customers/SeparatePageModels/Index" }, new { page = "/Customers/SeparatePageModels/Edit", id = "17" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pathData = route.GetVirtualPath(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(pathData);
|
||||||
|
Assert.Equal("/Customers/SeparatePageModels", pathData.VirtualPath);
|
||||||
|
Assert.Same(route, pathData.Router);
|
||||||
|
Assert.Empty(pathData.DataTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TreeRouter_GenerateLink_Match_WithParameters()
|
public void TreeRouter_GenerateLink_Match_WithParameters()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue