diff --git a/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplate.cs b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplate.cs
index 82da67cd47..5f99df178d 100644
--- a/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplate.cs
+++ b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplate.cs
@@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Routing
/// Defines a contract to generate a URL from a template.
///
///
- /// A can be created from
+ /// A can be created from
/// by supplying an address value which has matching endpoints. The returned
/// will be bound to the endpoints matching the address that was originally provided.
///
@@ -20,6 +20,9 @@ namespace Microsoft.AspNetCore.Routing
///
/// The associated with the current request.
/// The route values. Used to expand parameters in the route template. Optional.
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -29,6 +32,7 @@ namespace Microsoft.AspNetCore.Routing
public abstract string GetPath(
HttpContext httpContext,
object values,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default);
@@ -54,6 +58,15 @@ namespace Microsoft.AspNetCore.Routing
///
/// The associated with the current request.
/// The route values. Used to expand parameters in the route template. Optional.
+ ///
+ /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of will be used.
+ ///
+ ///
+ /// The URI host/authority, applied to the resulting URI. Optional. If not provided, the value will be used.
+ ///
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -63,6 +76,9 @@ namespace Microsoft.AspNetCore.Routing
public abstract string GetUri(
HttpContext httpContext,
object values,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default);
diff --git a/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplateOptions.cs b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplateOptions.cs
new file mode 100644
index 0000000000..18eb0f8c7c
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerationTemplateOptions.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNetCore.Routing
+{
+ ///
+ /// Contains options for creating a .
+ ///
+ public class LinkGenerationTemplateOptions
+ {
+ ///
+ /// Gets or sets a value indicating whether the template will use route values from the current request
+ /// when generating a URI.
+ ///
+ public bool UseAmbientValues { get; set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs
index e8659b3577..9f6bb0640f 100644
--- a/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs
+++ b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs
@@ -25,12 +25,16 @@ namespace Microsoft.AspNetCore.Routing
public abstract class LinkGenerator
{
///
- /// Generates a URI with an absolute path based on the provided values.
+ /// Generates a URI with an absolute path based on the provided values and .
///
/// The address type.
/// The associated with the current request.
/// The address value. Used to resolve endpoints.
/// The route values. Used to expand parameters in the route template. Optional.
+ /// The values associated with the current request. Optional.
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -41,6 +45,8 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
TAddress address,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default);
@@ -65,12 +71,22 @@ namespace Microsoft.AspNetCore.Routing
LinkOptions options = default);
///
- /// Generates an absolute URI based on the provided values.
+ /// Generates an absolute URI based on the provided values and .
///
/// The address type.
/// The associated with the current request.
/// The address value. Used to resolve endpoints.
/// The route values. Used to expand parameters in the route template. Optional.
+ /// The values associated with the current request. Optional.
+ ///
+ /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of will be used.
+ ///
+ ///
+ /// The URI host/authority, applied to the resulting URI. Optional. If not provided, the value will be used.
+ ///
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -81,6 +97,10 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
TAddress address,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues = default,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default);
@@ -113,9 +133,10 @@ namespace Microsoft.AspNetCore.Routing
///
/// The address type.
/// The address value. Used to resolve endpoints.
+ /// Options for the created .
///
/// A if one or more endpoints matching the address can be found, otherwise null.
///
- public abstract LinkGenerationTemplate GetTemplateByAddress(TAddress address);
+ public abstract LinkGenerationTemplate GetTemplateByAddress(TAddress address, LinkGenerationTemplateOptions options = null);
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerationTemplate.cs b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerationTemplate.cs
index b1beb67b1b..d1f83ca6e0 100644
--- a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerationTemplate.cs
+++ b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerationTemplate.cs
@@ -1,29 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
-using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Routing
{
internal sealed class DefaultLinkGenerationTemplate : LinkGenerationTemplate
{
- public DefaultLinkGenerationTemplate(DefaultLinkGenerator linkGenerator, List endpoints)
+ public DefaultLinkGenerationTemplate(DefaultLinkGenerator linkGenerator, List endpoints, LinkGenerationTemplateOptions options)
{
LinkGenerator = linkGenerator;
Endpoints = endpoints;
+ Options = options;
}
public DefaultLinkGenerator LinkGenerator { get; }
public List Endpoints { get; }
+ public LinkGenerationTemplateOptions Options { get; }
+
public override string GetPath(
HttpContext httpContext,
object values,
+ PathString? pathBase = default,
FragmentString fragment = default,
- LinkOptions options = null)
+ LinkOptions options = default)
{
if (httpContext == null)
{
@@ -32,9 +36,9 @@ namespace Microsoft.AspNetCore.Routing
return LinkGenerator.GetPathByEndpoints(
Endpoints,
- DefaultLinkGenerator.GetAmbientValues(httpContext),
new RouteValueDictionary(values),
- httpContext.Request.PathBase,
+ GetAmbientValues(httpContext),
+ pathBase ?? httpContext.Request.PathBase,
fragment,
options);
}
@@ -43,22 +47,25 @@ namespace Microsoft.AspNetCore.Routing
object values,
PathString pathBase = default,
FragmentString fragment = default,
- LinkOptions options = null)
+ LinkOptions options = default)
{
return LinkGenerator.GetPathByEndpoints(
Endpoints,
- ambientValues: null,
new RouteValueDictionary(values),
- pathBase,
- fragment,
- options);
+ ambientValues: null,
+ pathBase: pathBase,
+ fragment: fragment,
+ options: options);
}
public override string GetUri(
HttpContext httpContext,
object values,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
- LinkOptions options = null)
+ LinkOptions options = default)
{
if (httpContext == null)
{
@@ -67,11 +74,11 @@ namespace Microsoft.AspNetCore.Routing
return LinkGenerator.GetUriByEndpoints(
Endpoints,
- DefaultLinkGenerator.GetAmbientValues(httpContext),
new RouteValueDictionary(values),
- httpContext.Request.Scheme,
- httpContext.Request.Host,
- httpContext.Request.PathBase,
+ GetAmbientValues(httpContext),
+ scheme ?? httpContext.Request.Scheme,
+ host ?? httpContext.Request.Host,
+ pathBase ?? httpContext.Request.PathBase,
fragment,
options);
}
@@ -82,17 +89,32 @@ namespace Microsoft.AspNetCore.Routing
HostString host,
PathString pathBase = default,
FragmentString fragment = default,
- LinkOptions options = null)
+ LinkOptions options = default)
{
+ if (string.IsNullOrEmpty(scheme))
+ {
+ throw new ArgumentException("A scheme must be provided.", nameof(scheme));
+ }
+
+ if (!host.HasValue)
+ {
+ throw new ArgumentException("A host must be provided.", nameof(host));
+ }
+
return LinkGenerator.GetUriByEndpoints(
Endpoints,
- ambientValues: null,
new RouteValueDictionary(values),
- scheme,
- host,
- pathBase,
- fragment,
- options);
+ ambientValues: null,
+ scheme: scheme,
+ host: host,
+ pathBase: pathBase,
+ fragment: fragment,
+ options: options);
+ }
+
+ private RouteValueDictionary GetAmbientValues(HttpContext httpContext)
+ {
+ return (Options?.UseAmbientValues ?? false) ? DefaultLinkGenerator.GetAmbientValues(httpContext) : null;
}
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
index c303c5dcb2..7bd41daeaa 100644
--- a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
+++ b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
@@ -73,6 +73,8 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
TAddress address,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = null)
{
@@ -89,9 +91,9 @@ namespace Microsoft.AspNetCore.Routing
return GetPathByEndpoints(
endpoints,
- GetAmbientValues(httpContext),
values,
- httpContext.Request.PathBase,
+ ambientValues,
+ pathBase ?? httpContext.Request.PathBase,
fragment,
options);
}
@@ -111,17 +113,21 @@ namespace Microsoft.AspNetCore.Routing
return GetPathByEndpoints(
endpoints,
- ambientValues: null,
values,
- pathBase,
- fragment,
- options);
+ ambientValues: null,
+ pathBase: pathBase,
+ fragment: fragment,
+ options: options);
}
public override string GetUriByAddress(
HttpContext httpContext,
TAddress address,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues = default,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = null)
{
@@ -138,11 +144,11 @@ namespace Microsoft.AspNetCore.Routing
return GetUriByEndpoints(
endpoints,
- GetAmbientValues(httpContext),
values,
- httpContext.Request.Scheme,
- httpContext.Request.Host,
- httpContext.Request.PathBase,
+ ambientValues,
+ scheme ?? httpContext.Request.Scheme,
+ host ?? httpContext.Request.Host,
+ pathBase ?? httpContext.Request.PathBase,
fragment,
options);
}
@@ -156,9 +162,14 @@ namespace Microsoft.AspNetCore.Routing
FragmentString fragment = default,
LinkOptions options = null)
{
+ if (string.IsNullOrEmpty(scheme))
+ {
+ throw new ArgumentException("A scheme must be provided.", nameof(scheme));
+ }
+
if (!host.HasValue)
{
- throw new ArgumentNullException(nameof(host));
+ throw new ArgumentException("A host must be provided.", nameof(host));
}
var endpoints = GetEndpoints(address);
@@ -169,16 +180,16 @@ namespace Microsoft.AspNetCore.Routing
return GetUriByEndpoints(
endpoints,
- ambientValues: null,
values,
- scheme,
- host,
- pathBase,
- fragment,
- options);
+ ambientValues: null,
+ scheme: scheme,
+ host: host,
+ pathBase: pathBase,
+ fragment: fragment,
+ options: options);
}
- public override LinkGenerationTemplate GetTemplateByAddress(TAddress address)
+ public override LinkGenerationTemplate GetTemplateByAddress(TAddress address, LinkGenerationTemplateOptions options = default)
{
var endpoints = GetEndpoints(address);
if (endpoints.Count == 0)
@@ -186,7 +197,7 @@ namespace Microsoft.AspNetCore.Routing
return null;
}
- return new DefaultLinkGenerationTemplate(this, endpoints);
+ return new DefaultLinkGenerationTemplate(this, endpoints, options);
}
private List GetEndpoints(TAddress address)
@@ -209,8 +220,8 @@ namespace Microsoft.AspNetCore.Routing
// Also called from DefaultLinkGenerationTemplate
public string GetPathByEndpoints(
List endpoints,
- RouteValueDictionary ambientValues,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues,
PathString pathBase,
FragmentString fragment,
LinkOptions options)
@@ -220,11 +231,11 @@ namespace Microsoft.AspNetCore.Routing
var endpoint = endpoints[i];
if (TryProcessTemplate(
httpContext: null,
- endpoint,
+ endpoint: endpoint,
+ values: values,
ambientValues: ambientValues,
- values,
- options,
- out var result))
+ options: options,
+ result: out var result))
{
var uri = UriHelper.BuildRelative(
pathBase,
@@ -243,8 +254,8 @@ namespace Microsoft.AspNetCore.Routing
// Also called from DefaultLinkGenerationTemplate
public string GetUriByEndpoints(
List endpoints,
- RouteValueDictionary ambientValues,
RouteValueDictionary values,
+ RouteValueDictionary ambientValues,
string scheme,
HostString host,
PathString pathBase,
@@ -256,11 +267,11 @@ namespace Microsoft.AspNetCore.Routing
var endpoint = endpoints[i];
if (TryProcessTemplate(
httpContext: null,
- endpoint,
+ endpoint: endpoint,
+ values: values,
ambientValues: ambientValues,
- values,
- options,
- out var result))
+ options: options,
+ result: out var result))
{
var uri = UriHelper.BuildAbsolute(
scheme,
@@ -323,19 +334,19 @@ namespace Microsoft.AspNetCore.Routing
internal bool TryProcessTemplate(
HttpContext httpContext,
RouteEndpoint endpoint,
+ RouteValueDictionary values,
RouteValueDictionary ambientValues,
- RouteValueDictionary explicitValues,
LinkOptions options,
out (PathString path, QueryString query) result)
{
var templateBinder = GetTemplateBinder(endpoint);
- var templateValuesResult = templateBinder.GetValues(ambientValues, explicitValues);
+ var templateValuesResult = templateBinder.GetValues(ambientValues, values);
if (templateValuesResult == null)
{
// We're missing one of the required values for this route.
result = default;
- Log.TemplateFailedRequiredValues(_logger, endpoint, ambientValues, explicitValues);
+ Log.TemplateFailedRequiredValues(_logger, endpoint, ambientValues, values);
return false;
}
diff --git a/src/Microsoft.AspNetCore.Routing/LinkGeneratorEndpointNameAddressExtensions.cs b/src/Microsoft.AspNetCore.Routing/LinkGeneratorEndpointNameAddressExtensions.cs
index ab65be757e..a5904d1071 100644
--- a/src/Microsoft.AspNetCore.Routing/LinkGeneratorEndpointNameAddressExtensions.cs
+++ b/src/Microsoft.AspNetCore.Routing/LinkGeneratorEndpointNameAddressExtensions.cs
@@ -11,6 +11,11 @@ namespace Microsoft.AspNetCore.Routing
///
public static class LinkGeneratorEndpointNameAddressExtensions
{
+ private static readonly LinkGenerationTemplateOptions _templateOptions = new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = false,
+ };
+
///
/// Generates a URI with an absolute path based on the provided values.
///
@@ -18,6 +23,9 @@ namespace Microsoft.AspNetCore.Routing
/// The associated with the current request.
/// The endpoint name. Used to resolve endpoints.
/// The route values. Used to expand parameters in the route template. Optional.
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -29,6 +37,7 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
string endpointName,
object values,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default)
{
@@ -37,12 +46,24 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(generator));
}
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
if (endpointName == null)
{
throw new ArgumentNullException(nameof(endpointName));
}
- return generator.GetPathByAddress(httpContext, endpointName, new RouteValueDictionary(values), fragment, options);
+ return generator.GetPathByAddress(
+ httpContext,
+ endpointName,
+ new RouteValueDictionary(values),
+ ambientValues: null,
+ pathBase,
+ fragment,
+ options);
}
///
@@ -86,6 +107,15 @@ namespace Microsoft.AspNetCore.Routing
/// The associated with the current request.
/// The endpoint name. Used to resolve endpoints.
/// The route values. Used to expand parameters in the route template. Optional.
+ ///
+ /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of will be used.
+ ///
+ ///
+ /// The URI host/authority, applied to the resulting URI. Optional. If not provided, the value will be used.
+ ///
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -97,6 +127,9 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
string endpointName,
object values,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default)
{
@@ -105,12 +138,26 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(generator));
}
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
if (endpointName == null)
{
throw new ArgumentNullException(nameof(endpointName));
}
- return generator.GetUriByAddress(httpContext, endpointName, new RouteValueDictionary(values), fragment, options);
+ return generator.GetUriByAddress(
+ httpContext,
+ endpointName,
+ new RouteValueDictionary(values),
+ ambientValues: null,
+ scheme,
+ host,
+ pathBase,
+ fragment,
+ options);
}
///
@@ -147,7 +194,17 @@ namespace Microsoft.AspNetCore.Routing
{
throw new ArgumentNullException(nameof(endpointName));
}
-
+
+ if (string.IsNullOrEmpty(scheme))
+ {
+ throw new ArgumentException("A scheme must be provided.", nameof(scheme));
+ }
+
+ if (!host.HasValue)
+ {
+ throw new ArgumentException("A host must be provided.", nameof(host));
+ }
+
return generator.GetUriByAddress(endpointName, new RouteValueDictionary(values), scheme, host, pathBase, fragment, options);
}
@@ -171,7 +228,7 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(endpointName));
}
- return generator.GetTemplateByAddress(endpointName);
+ return generator.GetTemplateByAddress(endpointName, _templateOptions);
}
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/LinkGeneratorRouteValuesAddressExtensions.cs b/src/Microsoft.AspNetCore.Routing/LinkGeneratorRouteValuesAddressExtensions.cs
index 3f8014f8e2..a2bffc01ef 100644
--- a/src/Microsoft.AspNetCore.Routing/LinkGeneratorRouteValuesAddressExtensions.cs
+++ b/src/Microsoft.AspNetCore.Routing/LinkGeneratorRouteValuesAddressExtensions.cs
@@ -11,6 +11,11 @@ namespace Microsoft.AspNetCore.Routing
///
public static class LinkGeneratorRouteValuesAddressExtensions
{
+ private static readonly LinkGenerationTemplateOptions _templateOptions = new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = true,
+ };
+
///
/// Generates a URI with an absolute path based on the provided values.
///
@@ -18,6 +23,9 @@ namespace Microsoft.AspNetCore.Routing
/// The associated with the current request.
/// The route name. Used to resolve endpoints. Optional.
/// The route values. Used to resolve endpoints and expand parameters in the route template. Optional.
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -29,6 +37,7 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
string routeName,
object values,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default)
{
@@ -37,8 +46,20 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(generator));
}
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
var address = CreateAddress(httpContext, routeName, values);
- return generator.GetPathByAddress(httpContext, address, address.ExplicitValues, fragment, options);
+ return generator.GetPathByAddress(
+ httpContext,
+ address,
+ address.ExplicitValues,
+ address.AmbientValues,
+ pathBase,
+ fragment,
+ options);
}
///
@@ -78,6 +99,15 @@ namespace Microsoft.AspNetCore.Routing
/// The associated with the current request.
/// The route name. Used to resolve endpoints. Optional.
/// The route values. Used to resolve endpoints and expand parameters in the route template. Optional.
+ ///
+ /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of will be used.
+ ///
+ ///
+ /// The URI host/authority, applied to the resulting URI. Optional. If not provided, the value will be used.
+ ///
+ ///
+ /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used.
+ ///
/// An optional URI fragment. Appended to the resulting URI.
///
/// An optional . Settings on provided object override the settings with matching
@@ -89,6 +119,9 @@ namespace Microsoft.AspNetCore.Routing
HttpContext httpContext,
string routeName,
object values,
+ string scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions options = default)
{
@@ -97,8 +130,22 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(generator));
}
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
var address = CreateAddress(httpContext: null, routeName, values);
- return generator.GetUriByAddress(httpContext, address, address.ExplicitValues, fragment, options);
+ return generator.GetUriByAddress(
+ httpContext,
+ address,
+ address.ExplicitValues,
+ address.AmbientValues,
+ scheme,
+ host,
+ pathBase,
+ fragment,
+ options);
}
///
@@ -155,9 +202,9 @@ namespace Microsoft.AspNetCore.Routing
}
var address = CreateAddress(httpContext: null, routeName, values);
- return generator.GetTemplateByAddress(address);
+ return generator.GetTemplateByAddress(address, _templateOptions);
}
-
+
private static RouteValuesAddress CreateAddress(HttpContext httpContext, string routeName, object values)
{
return new RouteValuesAddress()
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGenerationTemplateTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGenerationTemplateTest.cs
index f76eec2f75..12f797fdea 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGenerationTemplateTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGenerationTemplateTest.cs
@@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: null);
// Act
var path = template.GetPath(
@@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Routing
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: null);
var httpContext = CreateHttpContext();
httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");
@@ -52,8 +52,8 @@ namespace Microsoft.AspNetCore.Routing
var path = template.GetPath(
httpContext,
values: new RouteValueDictionary(new { controller = "Home", action = "In?dex", query = "some?query" }),
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/In%3Fdex/?query=some%3Fquery#Fragment?", path);
@@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Routing
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: null);
// Act
var path = template.GetUri(
@@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Routing
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: null);
var httpContext = CreateHttpContext();
httpContext.Request.Scheme = "http";
@@ -101,22 +101,25 @@ namespace Microsoft.AspNetCore.Routing
var uri = template.GetUri(
httpContext,
values: new RouteValueDictionary(new { controller = "Home", action = "In?dex", query = "some?query" }),
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/In%3Fdex/?query=some%3Fquery#Fragment?", uri);
}
[Fact]
- public void GetPath_WithHttpContext_IncludesAmbientValues()
+ public void GetPath_WithHttpContext_IncludesAmbientValues_WhenUseAmbientValuesIsTrue()
{
// Arrange
var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}");
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = true,
+ });
var httpContext = CreateHttpContext(new { controller = "Home", });
httpContext.Request.Scheme = "http";
@@ -130,14 +133,41 @@ namespace Microsoft.AspNetCore.Routing
}
[Fact]
- public void GetUri_WithHttpContext_IncludesAmbientValues()
+ public void GetPath_WithHttpContext_ExcludesAmbientValues_WhenUseAmbientValuesIsFalse()
{
// Arrange
var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}");
var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
var linkGenerator = CreateLinkGenerator();
- var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, });
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = false,
+ });
+
+ var httpContext = CreateHttpContext(new { controller = "Home", });
+ httpContext.Request.Scheme = "http";
+ httpContext.Request.Host = new HostString("example.com");
+
+ // Act
+ var uri = template.GetPath(httpContext, values: new RouteValueDictionary(new { action = "Index", }));
+
+ // Assert
+ Assert.Null(uri);
+ }
+
+ [Fact]
+ public void GetUri_WithHttpContext_IncludesAmbientValues_WhenUseAmbientValuesIsTrue()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}");
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
+
+ var linkGenerator = CreateLinkGenerator();
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = true,
+ });
var httpContext = CreateHttpContext(new { controller = "Home", });
httpContext.Request.Scheme = "http";
@@ -149,5 +179,29 @@ namespace Microsoft.AspNetCore.Routing
// Assert
Assert.Equal("http://example.com/Home/Index", uri);
}
+
+ [Fact]
+ public void GetUri_WithHttpContext_ExcludesAmbientValues_WhenUseAmbientValuesIsFalse()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}");
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}");
+
+ var linkGenerator = CreateLinkGenerator();
+ var template = new DefaultLinkGenerationTemplate(linkGenerator, new List() { endpoint1, endpoint2, }, options: new LinkGenerationTemplateOptions()
+ {
+ UseAmbientValues = false,
+ });
+
+ var httpContext = CreateHttpContext(new { controller = "Home", });
+ httpContext.Request.Scheme = "http";
+ httpContext.Request.Host = new HostString("example.com");
+
+ // Act
+ var uri = template.GetUri(httpContext, values: new { action = "Index", });
+
+ // Assert
+ Assert.Null(uri);
+ }
}
}
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorProcessTemplateTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorProcessTemplateTest.cs
index ccda24efde..4f6792b47f 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorProcessTemplateTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorProcessTemplateTest.cs
@@ -25,10 +25,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: null,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "Home", p3 = "bar", }),
ambientValues: null,
- explicitValues: new RouteValueDictionary(new { p1 = "Home", p3 = "bar", }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -50,10 +50,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { path = routeValue, }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { path = routeValue, }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -82,10 +82,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { path = routeValue, }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { path = routeValue, }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -105,10 +105,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { path = "a/b b1/c c1" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { path = "a/b b1/c c1" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -128,10 +128,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { name = "name with %special #characters" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { name = "name with %special #characters" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -151,10 +151,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { color = new List { "red", "green", "blue" } }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { color = new List { "red", "green", "blue" } }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -174,10 +174,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { items = new List { 10, 20, 30 } }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { items = new List { 10, 20, 30 } }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -197,10 +197,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { color = new List { } }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { color = new List { } }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -220,10 +220,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { page = 1, color = new List { "red", "green", "blue" }, message = "textfortest" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { page = 1, color = new List { "red", "green", "blue" }, message = "textfortest" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -243,10 +243,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -266,10 +266,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -290,10 +290,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { id = "18" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { id = "18" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -314,10 +314,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { id = "18" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { id = "18" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -341,10 +341,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
- ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "П" }), // Cryillic uppercase Pe
+ values: new RouteValueDictionary(new { action = "П" }),
+ ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext), // Cryillic uppercase Pe
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -371,10 +371,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -396,10 +396,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -421,10 +421,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -446,13 +446,13 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "InDex" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "InDex" }),
options: new LinkOptions
{
LowercaseUrls = false
},
- out var result);
+ result: out var result);
// Assert
@@ -475,13 +475,13 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "InDex" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "InDex" }),
options: new LinkOptions()
{
LowercaseUrls = true
},
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -503,14 +503,14 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
options: new LinkOptions
{
LowercaseUrls = false,
LowercaseQueryStrings = false
},
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -532,14 +532,14 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", ShowStatus = "True", INFO = "DETAILED" }),
options: new LinkOptions()
{
LowercaseUrls = true,
LowercaseQueryStrings = true,
},
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -561,10 +561,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index" }),
options: new LinkOptions() { AppendTrailingSlash = true, },
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -587,10 +587,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "abcd" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { p1 = "abcd" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -611,10 +611,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -637,10 +637,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "abcd" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { p1 = "abcd" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -661,10 +661,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -698,10 +698,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { p1 = "hello", p2 = "1234" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -733,10 +733,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Store" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Store" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -766,10 +766,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Store" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Store" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -798,10 +798,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { controller = "Shopping" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { controller = "Shopping" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -832,10 +832,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Store", thirdthing = "13" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Store", thirdthing = "13" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -862,10 +862,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 4 }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 4 }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -888,10 +888,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = "not-an-integer" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = "not-an-integer" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -914,10 +914,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 98 }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 98 }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -940,10 +940,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -966,10 +966,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = "not-an-integer" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = "not-an-integer" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -992,10 +992,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 14 }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 14 }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1020,10 +1020,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 50 }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", id = 50 }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -1045,10 +1045,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1068,10 +1068,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1091,10 +1091,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1116,10 +1116,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1141,10 +1141,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1164,10 +1164,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products", format = "json" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products", format = "json" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1188,10 +1188,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home", name = "products" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1211,10 +1211,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
options: null,
- out var result);
+ result: out var result);
Assert.True(success);
@@ -1234,10 +1234,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { action = "Index", controller = "Home" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1257,10 +1257,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1280,10 +1280,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1303,10 +1303,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1407,10 +1407,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(explicitValues),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(explicitValues),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1435,10 +1435,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { c = "Products", a = "Edit" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { c = "Products", a = "Edit" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.True(success);
@@ -1463,10 +1463,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(new { c = "Products", a = "List" }),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(new { c = "Products", a = "List" }),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
@@ -1571,10 +1571,10 @@ namespace Microsoft.AspNetCore.Routing
var success = linkGenerator.TryProcessTemplate(
httpContext: httpContext,
endpoint: endpoint,
+ values: new RouteValueDictionary(explicitValues),
ambientValues: DefaultLinkGenerator.GetAmbientValues(httpContext),
- explicitValues: new RouteValueDictionary(explicitValues),
options: null,
- out var result);
+ result: out var result);
// Assert
Assert.False(success);
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs
index f64297e791..9f0bda2a18 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs
@@ -370,7 +370,7 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
1,
values: new RouteValueDictionary(new { controller = "Home", action = "In?dex", query = "some?query" }),
- new FragmentString("#Fragment?"));
+ fragment: new FragmentString("#Fragment?"));
// Assert
Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/In%3Fdex?query=some%3Fquery#Fragment?", path);
@@ -419,7 +419,7 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
1,
values: new RouteValueDictionary(new { controller = "Home", action = "In?dex", query = "some?query" }),
- new FragmentString("#Fragment?"));
+ fragment: new FragmentString("#Fragment?"));
// Assert
Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/In%3Fdex?query=some%3Fquery#Fragment?", uri);
@@ -434,12 +434,16 @@ namespace Microsoft.AspNetCore.Routing
var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
- var httpContext = CreateHttpContext(new { controller = "Home", });
+ var httpContext = CreateHttpContext();
httpContext.Request.Scheme = "http";
httpContext.Request.Host = new HostString("example.com");
// Act
- var uri = linkGenerator.GetPathByAddress(httpContext, 1, values: new RouteValueDictionary(new { action = "Index", }));
+ var uri = linkGenerator.GetPathByAddress(
+ httpContext,
+ 1,
+ values: new RouteValueDictionary(new { action = "Index", }),
+ ambientValues: new RouteValueDictionary(new { controller = "Home", }));
// Assert
Assert.Equal("/Home/Index", uri);
@@ -454,17 +458,71 @@ namespace Microsoft.AspNetCore.Routing
var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
- var httpContext = CreateHttpContext(new { controller = "Home", });
+ var httpContext = CreateHttpContext();
httpContext.Request.Scheme = "http";
httpContext.Request.Host = new HostString("example.com");
// Act
- var uri = linkGenerator.GetUriByAddress(httpContext, 1, values: new RouteValueDictionary(new { action = "Index", }));
+ var uri = linkGenerator.GetUriByAddress(
+ httpContext,
+ 1,
+ values: new RouteValueDictionary(new { action = "Index", }),
+ ambientValues: new RouteValueDictionary(new { controller = "Home", }));
// Assert
Assert.Equal("http://example.com/Home/Index", uri);
}
+ [Fact]
+ public void GetPathByAddress_WithHttpContext_CanOverrideUriParts()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}", metadata: new object[] { new IntMetadata(1), });
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}", metadata: new object[] { new IntMetadata(1), });
+
+ var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
+
+ var httpContext = CreateHttpContext();
+ httpContext.Request.PathBase = "/Foo";
+
+ // Act
+ var uri = linkGenerator.GetPathByAddress(
+ httpContext,
+ 1,
+ values: new RouteValueDictionary(new { action = "Index", controller= "Home", }),
+ pathBase: "/");
+
+ // Assert
+ Assert.Equal("/Home/Index", uri);
+ }
+
+ [Fact]
+ public void GetUriByAddress_WithHttpContext_CanOverrideUriParts()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}", metadata: new object[] { new IntMetadata(1), });
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id?}", metadata: new object[] { new IntMetadata(1), });
+
+ var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
+
+ var httpContext = CreateHttpContext();
+ httpContext.Request.Scheme = "http";
+ httpContext.Request.Host = new HostString("example.com");
+ httpContext.Request.PathBase = "/Foo";
+
+ // Act
+ var uri = linkGenerator.GetUriByAddress(
+ httpContext,
+ 1,
+ values: new RouteValueDictionary(new { action = "Index", controller = "Home", }),
+ scheme: "ftp",
+ host: new HostString("example.com:5000"),
+ pathBase: "/");
+
+ // Assert
+ Assert.Equal("ftp://example.com:5000/Home/Index", uri);
+ }
+
[Fact]
public void GetTemplateByAddress_WithNoMatch_ReturnsNull()
{
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorEndpointNameExtensionsTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorEndpointNameExtensionsTest.cs
index 0b57b598c7..ee16dc1666 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorEndpointNameExtensionsTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorEndpointNameExtensionsTest.cs
@@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Features;
using Xunit;
namespace Microsoft.AspNetCore.Routing
@@ -16,6 +17,37 @@ namespace Microsoft.AspNetCore.Routing
// Does not cover the EndpointNameEndpointFinder in detail. see EndpointNameEndpointFinderTest
public class LinkGeneratorEndpointNameExtensionsTest : LinkGeneratorTestBase
{
+ [Fact]
+ public void GetPathByName_WithHttpContext_DoesNotUseAmbientValues()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint("some-endpoint/{p}", metadata: new[] { new EndpointNameMetadata("name1"), });
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint("some#-other-endpoint/{p}", metadata: new[] { new EndpointNameMetadata("name2"), });
+
+ var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
+
+ var feature = new EndpointFeature()
+ {
+ RouteValues = new RouteValueDictionary(new { p = "5", })
+ };
+ var httpContext = CreateHttpContext();
+ httpContext.Features.Set(feature);
+ httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");
+
+ var values = new { query = "some?query", };
+
+ // Act
+ var path = linkGenerator.GetPathByName(
+ httpContext,
+ endpointName: "name2",
+ values,
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
+
+ // Assert
+ Assert.Null(path);
+ }
+
[Fact]
public void GetPathByName_WithoutHttpContext_WithPathBaseAndFragment()
{
@@ -58,8 +90,8 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
endpointName: "name2",
values,
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("/Foo/Bar%3Fencodeme%3F/some%23-other-endpoint/In%3Fdex/?query=some%3Fquery#Fragment?", path);
@@ -111,8 +143,8 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
endpointName: "name2",
values,
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/some%23-other-endpoint/In%3Fdex/?query=some%3Fquery#Fragment?", uri);
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorRouteValuesAddressExtensionsTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorRouteValuesAddressExtensionsTest.cs
index 17d5aa305a..57874816d6 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorRouteValuesAddressExtensionsTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/LinkGeneratorRouteValuesAddressExtensionsTest.cs
@@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Features;
using Xunit;
namespace Microsoft.AspNetCore.Routing
@@ -16,6 +17,41 @@ namespace Microsoft.AspNetCore.Routing
// Does not cover the RouteValueBasedEndpointFinder in detail. see RouteValueBasedEndpointFinderTest
public class LinkGeneratorRouteValuesAddressExtensionsTest : LinkGeneratorTestBase
{
+ [Fact]
+ public void GetPathByRouteValues_WithHttpContext_UsesAmbientValues()
+ {
+ // Arrange
+ var endpoint1 = EndpointFactory.CreateRouteEndpoint(
+ "Home/Index/{id}",
+ defaults: new { controller = "Home", action = "Index", },
+ metadata: new[] { new RouteValuesAddressMetadata(routeName: null, new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
+ var endpoint2 = EndpointFactory.CreateRouteEndpoint(
+ "Home/Index/{id?}",
+ defaults: new { controller = "Home", action = "Index", },
+ metadata: new[] { new RouteValuesAddressMetadata(routeName: null, new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
+
+ var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
+
+ var feature = new EndpointFeature()
+ {
+ RouteValues = new RouteValueDictionary(new { action = "Index", })
+ };
+ var httpContext = CreateHttpContext();
+ httpContext.Features.Set(feature);
+ httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");
+
+ // Act
+ var path = linkGenerator.GetPathByRouteValues(
+ httpContext,
+ routeName: null,
+ values: new RouteValueDictionary(new { controller = "Home", query = "some?query" }),
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
+
+ // Assert
+ Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path);
+ }
+
[Fact]
public void GetPathByRouteValues_WithoutHttpContext_WithPathBaseAndFragment()
{
@@ -66,8 +102,8 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
routeName: null,
values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }),
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path);
@@ -127,8 +163,8 @@ namespace Microsoft.AspNetCore.Routing
httpContext,
routeName: null,
values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }),
- new FragmentString("#Fragment?"),
- new LinkOptions() { AppendTrailingSlash = true, });
+ fragment: new FragmentString("#Fragment?"),
+ options: new LinkOptions() { AppendTrailingSlash = true, });
// Assert
Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", uri);