-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsfeature-routing
Milestone
Description
Background and Motivation
This is a follow up to #40438. Now that RouteValueDictionary's existing ctor is annotated as being trimmer unfriendly, it would make sense to provide alternatives in the framework where previously the framework
invoked the constructor on the user's behalf. For instance, in Http.Routing there are several APIs that do this. This proposal is to provide alternative overloads that accept an instance of RouteValueDictionary to avoid trimmer warnings.
Proposed API
namespace Microsoft.AspNetCore.Routing;
public static class LinkGeneratorEndpointNameAddressExtensions
{
public static string? GetPathByName(
this LinkGenerator generator,
HttpContext httpContext,
string endpointName,
object? values,
PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetPathByName(
+ this LinkGenerator generator,
+ HttpContext httpContext,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ PathString? pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetPathByName(
this LinkGenerator generator,
string endpointName,
object? values,
PathString pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetPathByName(
+ this LinkGenerator generator,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ PathString pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetUriByName(
this LinkGenerator generator,
HttpContext httpContext,
string endpointName,
object? values,
string? scheme = default,
HostString? host = default,
PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetUriByName(
+ this LinkGenerator generator,
+ HttpContext httpContext,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ string? scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetUriByName(
this LinkGenerator generator,
string endpointName,
object? values,
string scheme,
HostString host,
PathString pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetUriByName(
+ this LinkGenerator generator,
+ string endpointName,
+ RouteValueDictionary values, // Note that this is not nullable compared to the other API
+ string scheme,
+ HostString host,
+ PathString pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
}
public static class LinkGeneratorEndpointNameAddressExtensions
{
public static string? GetPathByName(
this LinkGenerator generator,
HttpContext httpContext,
string endpointName,
object? values,
PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetPathByName(
+ this LinkGenerator generator,
+ HttpContext httpContext,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ PathString? pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetPathByName(
this LinkGenerator generator,
string endpointName,
object? values,
PathString pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetPathByName(
+ this LinkGenerator generator,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ PathString pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetUriByName(
this LinkGenerator generator,
HttpContext httpContext,
string endpointName,
object? values,
string? scheme = default,
HostString? host = default,
PathString? pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetUriByName(
+ this LinkGenerator generator,
+ HttpContext httpContext,
+ string endpointName,
+ RouteValueDictionary? values = default,
+ string? scheme = default,
+ HostString? host = default,
+ PathString? pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
public static string? GetUriByName(
this LinkGenerator generator,
string endpointName,
object? values,
string scheme,
HostString host,
PathString pathBase = default,
FragmentString fragment = default,
LinkOptions? options = default);
+ public static string? GetUriByName(
+ this LinkGenerator generator,
+ string endpointName,
+ RouteValueDictionary values, // Note that this is not-nullable.
+ string scheme,
+ HostString host,
+ PathString pathBase = default,
+ FragmentString fragment = default,
+ LinkOptions? options = default);
}
namespace Microsoft.AspNetCore.Routing.Patterns;
public abstract class RoutePatternTransformer
{
public abstract RoutePattern? SubstituteRequiredValues(RoutePattern original, object requiredValues);
+ public virtual RoutePattern? SubstituteRequiredValues(RoutePattern original, RouteValueDictionary requiredValues);
}
public static class RoutePatternFactory
{
public static RoutePattern Parse(string pattern, object? defaults, object? parameterPolicies);
+ public static RoutePattern Parse(string pattern, RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies);
public static RoutePattern Parse(string pattern, object? defaults, object? parameterPolicies, object? requiredValues);
+ public static RoutePattern Parse(string pattern, RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies, RouteValueDictionary? requiredValues);
public static RoutePattern Pattern(object? defaults, object? parameterPolicies, IEnumerable<RoutePatternPathSegment> segments);
+ public static RoutePattern Pattern(RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies, IEnumerable<RoutePatternPathSegment> segments);
public static RoutePattern Pattern(string? rawText, object? defaults, object? parameterPolicies, IEnumerable<RoutePatternPathSegment> segments);
+ public static RoutePattern Pattern(string? rawText, RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies, IEnumerable<RoutePatternPathSegment> segments);
public static RoutePattern Pattern(object? defaults, object? parameterPolicies, params RoutePatternPathSegment[] segments);
+ public static RoutePattern Pattern(RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies, params RoutePatternPathSegment[] segments);
public static RoutePattern Pattern(string? rawText, object? defaults, object? parameterPolicies, params RoutePatternPathSegment[] segments);
+ public static RoutePattern Pattern(string? rawText, RouteValueDictionary? defaults, RouteValueDictionary? parameterPolicies, params RoutePatternPathSegment[] segments);
}Usage Examples
// Before
var myEndpoint = LinkGenerator.GetPathByName(context, "my-cool-endpoint", new { controller = "MyController" });
// After
var myEndpoint = LinkGenerator.GetPathByName(context, "my-cool-endpoint", new RouteValueDictionary { ["controller"] = "MyController" });
etc-->
Alternative Designs
Don't offer trimmer safe overloads. Users can still operate in a trimmer-safe way by passing an instance of RouteValueDictionary to existing overloads. This would prevent trimmer problems (such as getters on types getting trimmed), but continue to present trimmer warnings when publishing.
Risks
n/a
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsfeature-routing