TransformOutbound of route constraint is not called when the route segment is optional
#23,063 建立於 2020年6月17日
倉庫指標
- Star
- (37,933 star)
- PR 合併指標
- (平均合併 16天 9小時) (30 天內合併 258 個 PR)
描述
Describe the bug
TransformOutbound is not callled when generating url when the constraint in the route template is is optional.
To Reproduce
The Index page show that the last segment of the 2 urls are different when they shouldn't Route.cshtml as the route definition @page "{id:hex}" RouteWithOptionalSegment.cshtml as the route definition @page "{id:hex?}"
The problem is that OptionalRouteConstraint, that wrap the specified route contraint, does not implement IOutboundParameterTransformer, therefore _parameterTransformers in TemplateBinder is not initialized correctly.
One possible fix is to define
class OutboundParameterTransformerOptionalRouteConstraint : OptionalRouteConstraint, IOutboundParameterTransformer
{
public OutboundParameterTransformerOptionalRouteConstraint(IRouteConstraint innerConstraint) : base(innerConstraint)
{
}
public string TransformOutbound(object value) => ((IOutboundParameterTransformer)InnerConstraint).TransformOutbound(value);
}
and have the DefaultParameterPolicy's InitializeRouteConstraint method return an instance of it when the constraint is optional and the routeConstraint implements IOutboundParameterTransformer.
private IParameterPolicy InitializeRouteConstraint(bool optional, IRouteConstraint routeConstraint)
{
if (!optional)
return routeConstraint;
else if (routeConstraint is IOutboundParameterTransformer)
return new OutboundParameterTransformerOptionalRouteConstraint(routeConstraint);
else
return new OptionalRouteConstraint(routeConstraint);
}
Further technical details
- ASP.NET Core version 3.1
.NET Core SDK (reflecting any global.json): Version: 3.1.301 Commit: 7feb845744
Runtime Environment: OS Name: Windows OS Version: 10.0.18362 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\3.1.301\
Host (useful for support): Version: 3.1.5 Commit: 65cd789777
.NET Core SDKs installed: 1.1.14 [C:\Program Files\dotnet\sdk] 2.1.401 [C:\Program Files\dotnet\sdk] 2.1.802 [C:\Program Files\dotnet\sdk] 2.2.103 [C:\Program Files\dotnet\sdk] 3.1.200 [C:\Program Files\dotnet\sdk] 3.1.202 [C:\Program Files\dotnet\sdk] 3.1.301 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 1.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]