Created LinkGenerationTemplate and friends
This commit is contained in:
parent
b177ba5309
commit
c8946a40e4
|
|
@ -0,0 +1,29 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a contract to generate a URL from a template.
|
||||
/// </summary>
|
||||
public abstract class LinkGenerationTemplate
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string MakeUrl(object values)
|
||||
{
|
||||
return MakeUrl(values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values and link options.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public abstract string MakeUrl(object values, LinkOptions options);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,78 +6,191 @@ using Microsoft.AspNetCore.Http;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a contract to generate URLs to endpoints.
|
||||
/// </summary>
|
||||
public abstract class LinkGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(object values)
|
||||
{
|
||||
return GetLink(httpContext: null, routeName: null, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values and link options.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(object values, LinkOptions options)
|
||||
{
|
||||
return GetLink(httpContext: null, routeName: null, values, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(object values, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext: null, routeName: null, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values and link options.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(object values, LinkOptions options, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext: null, routeName: null, values, options, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(HttpContext httpContext, object values)
|
||||
{
|
||||
return GetLink(httpContext, routeName: null, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(HttpContext httpContext, object values, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext, routeName: null, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values and link options.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(HttpContext httpContext, object values, LinkOptions options)
|
||||
{
|
||||
return GetLink(httpContext, routeName: null, values, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route values and link options.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(HttpContext httpContext, object values, LinkOptions options, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext, routeName: null, values, options, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name and route values.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(string routeName, object values)
|
||||
{
|
||||
return GetLink(httpContext: null, routeName, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name and route values.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(string routeName, object values, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext: null, routeName, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name and route values.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(string routeName, object values, LinkOptions options)
|
||||
{
|
||||
return GetLink(httpContext: null, routeName, values, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name, route values and link options.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(string routeName, object values, LinkOptions options, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext: null, routeName, values, options, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name and route values.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(HttpContext httpContext, string routeName, object values)
|
||||
{
|
||||
return GetLink(httpContext, routeName, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name and route values.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLink(HttpContext httpContext, string routeName, object values, out string link)
|
||||
{
|
||||
return TryGetLink(httpContext, routeName, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name, route values and link options.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLink(HttpContext httpContext, string routeName, object values, LinkOptions options)
|
||||
{
|
||||
if (TryGetLink(httpContext, routeName, values, options, out var link))
|
||||
|
|
@ -88,6 +201,16 @@ namespace Microsoft.AspNetCore.Routing
|
|||
throw new InvalidOperationException("Could not find a matching endpoint to generate a link.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified route name, route values and link options.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public abstract bool TryGetLink(
|
||||
HttpContext httpContext,
|
||||
string routeName,
|
||||
|
|
@ -95,51 +218,119 @@ namespace Microsoft.AspNetCore.Routing
|
|||
LinkOptions options,
|
||||
out string link);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information and route values.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLinkByAddress<TAddress>(TAddress address, object values)
|
||||
{
|
||||
return GetLinkByAddress(address, httpContext: null, values, options: null);
|
||||
return GetLinkByAddress(httpContext: null, address, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information and route values.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLinkByAddress<TAddress>(TAddress address, object values, out string link)
|
||||
{
|
||||
return TryGetLinkByAddress(address, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information, route values and link options.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLinkByAddress<TAddress>(TAddress address, object values, LinkOptions options)
|
||||
{
|
||||
return GetLinkByAddress(address, httpContext: null, values, options);
|
||||
return GetLinkByAddress(httpContext: null, address, values, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information, route values and link options.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLinkByAddress<TAddress>(
|
||||
TAddress address,
|
||||
object values,
|
||||
LinkOptions options,
|
||||
out string link)
|
||||
{
|
||||
return TryGetLinkByAddress(address, httpContext: null, values, options, out link);
|
||||
return TryGetLinkByAddress(httpContext: null, address, values, options, out link);
|
||||
}
|
||||
|
||||
public string GetLinkByAddress<TAddress>(TAddress address, HttpContext httpContext, object values)
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information, route values and link options.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLinkByAddress<TAddress>(HttpContext httpContext, TAddress address, object values)
|
||||
{
|
||||
return GetLinkByAddress(address, httpContext, values, options: null);
|
||||
return GetLinkByAddress(httpContext, address, values, options: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information and route values.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetLinkByAddress<TAddress>(
|
||||
TAddress address,
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object values,
|
||||
out string link)
|
||||
{
|
||||
return TryGetLinkByAddress(address, httpContext, values, options: null, out link);
|
||||
return TryGetLinkByAddress(httpContext, address, values, options: null, out link);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information, route values and link options.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <returns>The generated URL.</returns>
|
||||
public string GetLinkByAddress<TAddress>(
|
||||
TAddress address,
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object values,
|
||||
LinkOptions options)
|
||||
{
|
||||
if (TryGetLinkByAddress(address, httpContext, values, options, out var link))
|
||||
if (TryGetLinkByAddress(httpContext, address, values, options, out var link))
|
||||
{
|
||||
return link;
|
||||
}
|
||||
|
|
@ -147,11 +338,126 @@ namespace Microsoft.AspNetCore.Routing
|
|||
throw new InvalidOperationException("Could not find a matching endpoint to generate a link.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URL with an absolute path from the specified lookup information, route values and link options.
|
||||
/// This lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// A return value indicates whether the operation succeeded.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for generating a URL.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">An object that contains route values.</param>
|
||||
/// <param name="options">The <see cref="LinkOptions"/>.</param>
|
||||
/// <param name="link">The generated URL.</param>
|
||||
/// <returns><c>true</c> if a URL was generated successfully; otherwise, <c>false</c>.</returns>
|
||||
public abstract bool TryGetLinkByAddress<TAddress>(
|
||||
TAddress address,
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object values,
|
||||
LinkOptions options,
|
||||
out string link);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified route values.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// </summary>
|
||||
/// <param name="values">
|
||||
/// An object that contains route values. These values are used to lookup endpoint(s).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public LinkGenerationTemplate GetTemplate(object values)
|
||||
{
|
||||
return GetTemplate(httpContext: null, routeName: null, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified route name and route values.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">
|
||||
/// An object that contains route values. These values are used to lookup for endpoint(s).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public LinkGenerationTemplate GetTemplate(string routeName, object values)
|
||||
{
|
||||
return GetTemplate(httpContext: null, routeName, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified route values.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="values">
|
||||
/// An object that contains route values. These values are used to lookup for endpoint(s).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public LinkGenerationTemplate GetTemplate(HttpContext httpContext, object values)
|
||||
{
|
||||
return GetTemplate(httpContext, routeName: null, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified route name and route values.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <param name="routeName">The name of the route to generate the URL to.</param>
|
||||
/// <param name="values">
|
||||
/// An object that contains route values. These values are used to lookup for endpoint(s).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public abstract LinkGenerationTemplate GetTemplate(HttpContext httpContext, string routeName, object values);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified lookup information.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// The lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for creating a template.</param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public LinkGenerationTemplate GetTemplateByAddress<TAddress>(TAddress address)
|
||||
{
|
||||
return GetTemplateByAddress(httpContext: null, address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="LinkGenerationTemplate"/> to generate a URL from the specified lookup information.
|
||||
/// This template object holds information of the endpoint(s) that were found and which can later be used to
|
||||
/// generate a URL using the <see cref="LinkGenerationTemplate.MakeUrl(object, LinkOptions)"/> api.
|
||||
/// The lookup information is used to find endpoints using a registered 'IEndpointFinder<TAddress>'.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
/// <param name="address">The information used to look up endpoints for creating a template.</param>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> associated with current request.</param>
|
||||
/// <returns>
|
||||
/// If an endpoint(s) was found successfully, then this returns a template object representing that,
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
public abstract LinkGenerationTemplate GetTemplateByAddress<TAddress>(
|
||||
HttpContext httpContext,
|
||||
TAddress address);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
// 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 System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
internal class DefaultLinkGenerationTemplate : LinkGenerationTemplate
|
||||
{
|
||||
public DefaultLinkGenerationTemplate(
|
||||
DefaultLinkGenerator linkGenerator,
|
||||
IEnumerable<MatcherEndpoint> endpoints,
|
||||
HttpContext httpContext,
|
||||
RouteValueDictionary explicitValues,
|
||||
RouteValueDictionary ambientValues)
|
||||
{
|
||||
LinkGenerator = linkGenerator;
|
||||
Endpoints = endpoints;
|
||||
HttpContext = httpContext;
|
||||
EarlierExplicitValues = explicitValues;
|
||||
AmbientValues = ambientValues;
|
||||
}
|
||||
|
||||
internal DefaultLinkGenerator LinkGenerator { get; }
|
||||
|
||||
internal IEnumerable<MatcherEndpoint> Endpoints { get; }
|
||||
|
||||
internal HttpContext HttpContext { get; }
|
||||
|
||||
internal RouteValueDictionary EarlierExplicitValues { get; }
|
||||
|
||||
internal RouteValueDictionary AmbientValues { get; }
|
||||
|
||||
public override string MakeUrl(object values, LinkOptions options)
|
||||
{
|
||||
var currentValues = new RouteValueDictionary(values);
|
||||
var mergedValuesDictionary = new RouteValueDictionary(EarlierExplicitValues);
|
||||
|
||||
foreach (var kvp in currentValues)
|
||||
{
|
||||
mergedValuesDictionary[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
foreach (var endpoint in Endpoints)
|
||||
{
|
||||
var link = LinkGenerator.MakeLink(
|
||||
HttpContext,
|
||||
endpoint,
|
||||
AmbientValues,
|
||||
mergedValuesDictionary,
|
||||
options);
|
||||
if (link != null)
|
||||
{
|
||||
return link;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
|
@ -54,21 +55,78 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
|
||||
public override bool TryGetLinkByAddress<TAddress>(
|
||||
TAddress address,
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object values,
|
||||
LinkOptions options,
|
||||
out string link)
|
||||
{
|
||||
return TryGetLinkByAddressInternal(
|
||||
address,
|
||||
httpContext,
|
||||
address,
|
||||
explicitValues: values,
|
||||
ambientValues: GetAmbientValues(httpContext),
|
||||
options,
|
||||
out link);
|
||||
}
|
||||
|
||||
public override LinkGenerationTemplate GetTemplate(HttpContext httpContext, string routeName, object values)
|
||||
{
|
||||
var ambientValues = GetAmbientValues(httpContext);
|
||||
var explicitValues = new RouteValueDictionary(values);
|
||||
|
||||
return GetTemplateInternal(
|
||||
httpContext,
|
||||
new RouteValuesAddress
|
||||
{
|
||||
RouteName = routeName,
|
||||
ExplicitValues = explicitValues,
|
||||
AmbientValues = ambientValues
|
||||
},
|
||||
ambientValues,
|
||||
explicitValues,
|
||||
values);
|
||||
}
|
||||
|
||||
public override LinkGenerationTemplate GetTemplateByAddress<TAddress>(
|
||||
HttpContext httpContext,
|
||||
TAddress address)
|
||||
{
|
||||
return GetTemplateInternal(httpContext, address, values: null);
|
||||
}
|
||||
|
||||
internal string MakeLink(
|
||||
HttpContext httpContext,
|
||||
MatcherEndpoint endpoint,
|
||||
RouteValueDictionary ambientValues,
|
||||
RouteValueDictionary explicitValues,
|
||||
LinkOptions options)
|
||||
{
|
||||
var templateBinder = new TemplateBinder(
|
||||
UrlEncoder.Default,
|
||||
_uriBuildingContextPool,
|
||||
new RouteTemplate(endpoint.RoutePattern),
|
||||
new RouteValueDictionary(endpoint.RoutePattern.Defaults));
|
||||
|
||||
var templateValuesResult = templateBinder.GetValues(
|
||||
ambientValues: ambientValues,
|
||||
explicitValues: explicitValues,
|
||||
requiredKeys: endpoint.RequiredValues.Keys);
|
||||
if (templateValuesResult == null)
|
||||
{
|
||||
// We're missing one of the required values for this route.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!MatchesConstraints(httpContext, endpoint, templateValuesResult.CombinedValues))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var url = templateBinder.BindValues(templateValuesResult.AcceptedValues);
|
||||
return Normalize(url, options);
|
||||
}
|
||||
|
||||
private bool TryGetLinkByRouteValues(
|
||||
HttpContext httpContext,
|
||||
string routeName,
|
||||
|
|
@ -86,8 +144,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
};
|
||||
|
||||
return TryGetLinkByAddressInternal(
|
||||
address,
|
||||
httpContext,
|
||||
address,
|
||||
explicitValues: values,
|
||||
ambientValues: ambientValues,
|
||||
options,
|
||||
|
|
@ -95,8 +153,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
|
||||
private bool TryGetLinkByAddressInternal<TAddress>(
|
||||
TAddress address,
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object explicitValues,
|
||||
RouteValueDictionary ambientValues,
|
||||
LinkOptions options,
|
||||
|
|
@ -104,22 +162,21 @@ namespace Microsoft.AspNetCore.Routing
|
|||
{
|
||||
link = null;
|
||||
|
||||
var endpointFinder = _serviceProvider.GetRequiredService<IEndpointFinder<TAddress>>();
|
||||
var endpoints = endpointFinder.FindEndpoints(address);
|
||||
var endpoints = FindEndpoints(address);
|
||||
if (endpoints == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var matcherEndpoints = endpoints.OfType<MatcherEndpoint>();
|
||||
if (!matcherEndpoints.Any())
|
||||
foreach (var endpoint in endpoints)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
link = MakeLink(
|
||||
httpContext,
|
||||
endpoint,
|
||||
ambientValues,
|
||||
new RouteValueDictionary(explicitValues),
|
||||
options);
|
||||
|
||||
foreach (var endpoint in matcherEndpoints)
|
||||
{
|
||||
link = GetLink(endpoint);
|
||||
if (link != null)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -127,33 +184,49 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string GetLink(MatcherEndpoint endpoint)
|
||||
private LinkGenerationTemplate GetTemplateInternal<TAddress>(
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
object values)
|
||||
{
|
||||
var endpoints = FindEndpoints(address);
|
||||
if (endpoints == null)
|
||||
{
|
||||
var templateBinder = new TemplateBinder(
|
||||
UrlEncoder.Default,
|
||||
_uriBuildingContextPool,
|
||||
new RouteTemplate(endpoint.RoutePattern),
|
||||
new RouteValueDictionary(endpoint.RoutePattern.Defaults));
|
||||
|
||||
var templateValuesResult = templateBinder.GetValues(
|
||||
ambientValues: ambientValues,
|
||||
explicitValues: new RouteValueDictionary(explicitValues),
|
||||
requiredKeys: endpoint.RequiredValues.Keys);
|
||||
if (templateValuesResult == null)
|
||||
{
|
||||
// We're missing one of the required values for this route.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!MatchesConstraints(httpContext, endpoint, templateValuesResult.CombinedValues))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var url = templateBinder.BindValues(templateValuesResult.AcceptedValues);
|
||||
return Normalize(url, options);
|
||||
return null;
|
||||
}
|
||||
|
||||
var ambientValues = GetAmbientValues(httpContext);
|
||||
var explicitValues = new RouteValueDictionary(values);
|
||||
|
||||
return new DefaultLinkGenerationTemplate(
|
||||
this,
|
||||
endpoints,
|
||||
httpContext,
|
||||
explicitValues,
|
||||
ambientValues);
|
||||
}
|
||||
|
||||
private LinkGenerationTemplate GetTemplateInternal<TAddress>(
|
||||
HttpContext httpContext,
|
||||
TAddress address,
|
||||
RouteValueDictionary ambientValues,
|
||||
RouteValueDictionary explicitValues,
|
||||
object values)
|
||||
{
|
||||
var endpoints = FindEndpoints(address);
|
||||
if (endpoints == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DefaultLinkGenerationTemplate(
|
||||
this,
|
||||
endpoints,
|
||||
httpContext,
|
||||
explicitValues,
|
||||
ambientValues);
|
||||
}
|
||||
|
||||
private bool MatchesConstraints(
|
||||
|
|
@ -234,7 +307,25 @@ namespace Microsoft.AspNetCore.Routing
|
|||
return feature.Values;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return new RouteValueDictionary();
|
||||
}
|
||||
|
||||
private IEnumerable<MatcherEndpoint> FindEndpoints<TAddress>(TAddress address)
|
||||
{
|
||||
var finder = _serviceProvider.GetRequiredService<IEndpointFinder<TAddress>>();
|
||||
var endpoints = finder.FindEndpoints(address);
|
||||
if (endpoints == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var matcherEndpoints = endpoints.OfType<MatcherEndpoint>();
|
||||
if (!matcherEndpoints.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return matcherEndpoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a contract to find endpoints based on the supplied lookup information.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAddress">The address type to look up endpoints.</typeparam>
|
||||
public interface IEndpointFinder<TAddress>
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds endpoints based on the supplied lookup information.
|
||||
/// </summary>
|
||||
/// <param name="address">The information used to look up endpoints.</param>
|
||||
/// <returns>A collection of <see cref="Endpoint"/>.</returns>
|
||||
IEnumerable<Endpoint> FindEndpoints(TAddress address);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1217,7 +1217,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetLink_WithCustomAddress_CanGenerateLink()
|
||||
public void TryGetLinkByAddress_WithCustomAddress_CanGenerateLink()
|
||||
{
|
||||
// Arrange
|
||||
var services = GetBasicServices();
|
||||
|
|
@ -1237,8 +1237,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
// Act
|
||||
var canGenerateLink = linkGenerator.TryGetLinkByAddress<INameMetadata>(
|
||||
address: new NameMetadata("CustomerDetails"),
|
||||
httpContext,
|
||||
address: new NameMetadata("CustomerDetails"),
|
||||
values: new { id = 10 },
|
||||
out var link);
|
||||
|
||||
|
|
@ -1248,7 +1248,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetLink_WithCustomAddress_CanGenerateLink_RespectsLinkOptions_SuppliedAtCallSite()
|
||||
public void TryGetLinkByAddress_WithCustomAddress_CanGenerateLink_RespectsLinkOptions_SuppliedAtCallSite()
|
||||
{
|
||||
// Arrange
|
||||
var services = GetBasicServices();
|
||||
|
|
@ -1268,8 +1268,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
// Act
|
||||
var canGenerateLink = linkGenerator.TryGetLinkByAddress<INameMetadata>(
|
||||
address: new NameMetadata("CustomerDetails"),
|
||||
httpContext,
|
||||
address: new NameMetadata("CustomerDetails"),
|
||||
values: new { id = 10 },
|
||||
new LinkOptions
|
||||
{
|
||||
|
|
@ -1282,6 +1282,177 @@ namespace Microsoft.AspNetCore.Routing
|
|||
Assert.Equal("/customers/details/10", link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTemplate_ByRouteValues_ReturnsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null });
|
||||
var linkGenerator = CreateLinkGenerator(endpoint1);
|
||||
var values = new RouteValueDictionary(new { controller = "Product", action = "Edit" });
|
||||
|
||||
// Act
|
||||
var template = linkGenerator.GetTemplate(values);
|
||||
|
||||
// Assert
|
||||
var defaultTemplate = Assert.IsType<DefaultLinkGenerationTemplate>(template);
|
||||
Assert.Same(linkGenerator, defaultTemplate.LinkGenerator);
|
||||
Assert.Equal(new[] { endpoint1 }, defaultTemplate.Endpoints);
|
||||
Assert.Equal(values, defaultTemplate.EarlierExplicitValues);
|
||||
Assert.Null(defaultTemplate.HttpContext);
|
||||
Assert.Empty(defaultTemplate.AmbientValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTemplate_ByRouteName_ReturnsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
metadata: new RouteNameMetadata("EditProduct"));
|
||||
var linkGenerator = CreateLinkGenerator(endpoint1);
|
||||
|
||||
// Act
|
||||
var template = linkGenerator.GetTemplate("EditProduct", values: new { });
|
||||
|
||||
// Assert
|
||||
var defaultTemplate = Assert.IsType<DefaultLinkGenerationTemplate>(template);
|
||||
Assert.Same(linkGenerator, defaultTemplate.LinkGenerator);
|
||||
Assert.Equal(new[] { endpoint1 }, defaultTemplate.Endpoints);
|
||||
Assert.Empty(defaultTemplate.EarlierExplicitValues);
|
||||
Assert.Null(defaultTemplate.HttpContext);
|
||||
Assert.Empty(defaultTemplate.AmbientValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTemplate_ByRouteName_ReturnsTemplate_WithMultipleEndpoints()
|
||||
{
|
||||
// Arrange
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
metadata: new RouteNameMetadata("default"));
|
||||
var endpoint2 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Details/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
metadata: new RouteNameMetadata("default"));
|
||||
var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);
|
||||
|
||||
// Act
|
||||
var template = linkGenerator.GetTemplate("default", values: new { });
|
||||
|
||||
// Assert
|
||||
var defaultTemplate = Assert.IsType<DefaultLinkGenerationTemplate>(template);
|
||||
Assert.Same(linkGenerator, defaultTemplate.LinkGenerator);
|
||||
Assert.Equal(new[] { endpoint1, endpoint2 }, defaultTemplate.Endpoints);
|
||||
Assert.Empty(defaultTemplate.EarlierExplicitValues);
|
||||
Assert.Null(defaultTemplate.HttpContext);
|
||||
Assert.Empty(defaultTemplate.AmbientValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTemplateByAddress_ByCustomAddress_ReturnsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var services = GetBasicServices();
|
||||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Singleton<IEndpointFinder<INameMetadata>, EndpointFinderByName>());
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null });
|
||||
var endpoint2 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Customers/Details/{id}",
|
||||
requiredValues: new { controller = "Customers", action = "Details" },
|
||||
defaults: new { controller = "Customers", action = "Details" },
|
||||
metadata: new NameMetadata("CustomerDetails"));
|
||||
var linkGenerator = CreateLinkGenerator(new[] { endpoint1, endpoint2 }, new RouteOptions(), services);
|
||||
|
||||
// Act
|
||||
var template = linkGenerator.GetTemplateByAddress<INameMetadata>(new NameMetadata("CustomerDetails"));
|
||||
|
||||
// Assert
|
||||
var defaultTemplate = Assert.IsType<DefaultLinkGenerationTemplate>(template);
|
||||
Assert.Same(linkGenerator, defaultTemplate.LinkGenerator);
|
||||
Assert.Equal(new[] { endpoint2 }, defaultTemplate.Endpoints);
|
||||
Assert.Empty(defaultTemplate.EarlierExplicitValues);
|
||||
Assert.Null(defaultTemplate.HttpContext);
|
||||
Assert.Empty(defaultTemplate.AmbientValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeUrl_Honors_LinkOptions()
|
||||
{
|
||||
// Arrange
|
||||
var services = GetBasicServices();
|
||||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Singleton<IEndpointFinder<INameMetadata>, EndpointFinderByName>());
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null });
|
||||
var endpoint2 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Customers/Details/{id}",
|
||||
requiredValues: new { controller = "Customers", action = "Details" },
|
||||
defaults: new { controller = "Customers", action = "Details" },
|
||||
metadata: new NameMetadata("CustomerDetails"));
|
||||
var linkGenerator = CreateLinkGenerator(new[] { endpoint1, endpoint2 }, new RouteOptions(), services);
|
||||
|
||||
// Act1
|
||||
var template = linkGenerator.GetTemplateByAddress<INameMetadata>(new NameMetadata("CustomerDetails"));
|
||||
|
||||
// Assert1
|
||||
Assert.NotNull(template);
|
||||
|
||||
// Act2
|
||||
var link = template.MakeUrl(new { id = 10 }, new LinkOptions { LowercaseUrls = true });
|
||||
|
||||
// Assert2
|
||||
Assert.Equal("/customers/details/10", link);
|
||||
|
||||
// Act3
|
||||
link = template.MakeUrl(new { id = 25 });
|
||||
|
||||
// Assert3
|
||||
Assert.Equal("/Customers/Details/25", link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeUrl_GeneratesLink_WithExtraRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var endpoint1 = EndpointFactory.CreateMatcherEndpoint(
|
||||
"Product/Edit/{id}",
|
||||
requiredValues: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null },
|
||||
defaults: new { controller = "Product", action = "Edit", area = (string)null, page = (string)null });
|
||||
var linkGenerator = CreateLinkGenerator(endpoint1);
|
||||
|
||||
// Act1
|
||||
var template = linkGenerator.GetTemplate(
|
||||
values: new { controller = "Product", action = "Edit", foo = "bar" });
|
||||
|
||||
// Assert1
|
||||
Assert.NotNull(template);
|
||||
|
||||
// Act2
|
||||
var link = template.MakeUrl(new { id = 10 });
|
||||
|
||||
// Assert2
|
||||
Assert.Equal("/Product/Edit/10?foo=bar", link);
|
||||
|
||||
// Act3
|
||||
link = template.MakeUrl(new { id = 25, foo = "boo" });
|
||||
|
||||
// Assert3
|
||||
Assert.Equal("/Product/Edit/25?foo=boo", link);
|
||||
}
|
||||
|
||||
private LinkGenerator CreateLinkGenerator(params Endpoint[] endpoints)
|
||||
{
|
||||
return CreateLinkGenerator(endpoints, routeOptions: null);
|
||||
|
|
@ -1365,5 +1536,14 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
public string Name { get; }
|
||||
}
|
||||
|
||||
private class RouteNameMetadata : IRouteNameMetadata
|
||||
{
|
||||
public RouteNameMetadata(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
public string Name { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue