22using System . Text ;
33using System . Threading . Tasks ;
44using Microsoft . AspNetCore . Hosting ;
5- using Microsoft . AspNetCore . Http ;
6- using Microsoft . AspNetCore . Http . Extensions ;
5+ using Microsoft . AspNetCore . Http . Features ;
76using Microsoft . AspNetCore . Mvc . ViewFeatures ;
87using Microsoft . AspNetCore . Mvc . Rendering ;
98using Microsoft . AspNetCore . NodeServices ;
109using Microsoft . AspNetCore . Razor . TagHelpers ;
11- using Microsoft . Extensions . PlatformAbstractions ;
1210using Newtonsoft . Json ;
1311
1412namespace Microsoft . AspNetCore . SpaServices . Prerendering
@@ -60,7 +58,19 @@ public PrerenderTagHelper(IServiceProvider serviceProvider)
6058
6159 public override async Task ProcessAsync ( TagHelperContext context , TagHelperOutput output )
6260 {
61+ // We want to pass the original, unencoded incoming URL data through to Node, so that
62+ // server-side code has the same view of the URL as client-side code (on the client,
63+ // location.pathname returns an unencoded string).
64+ // The following logic handles special characters in URL paths in the same way that
65+ // Node and client-side JS does. For example, the path "/a=b%20c" gets passed through
66+ // unchanged (whereas other .NET APIs do change it - Path.Value will return it as
67+ // "/a=b c" and Path.ToString() will return it as "/a%3db%20c")
68+ var requestFeature = ViewContext . HttpContext . Features . Get < IHttpRequestFeature > ( ) ;
69+ var unencodedPathAndQuery = requestFeature . RawTarget ;
70+
6371 var request = ViewContext . HttpContext . Request ;
72+ var unencodedAbsoluteUrl = $ "{ request . Scheme } ://{ request . Host } { unencodedPathAndQuery } ";
73+
6474 var result = await Prerenderer . RenderToString (
6575 _applicationBasePath ,
6676 _nodeServices ,
@@ -69,8 +79,8 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
6979 ExportName = ExportName ,
7080 WebpackConfig = WebpackConfigPath
7181 } ,
72- request . GetEncodedUrl ( ) ,
73- request . Path + request . QueryString . Value ,
82+ unencodedAbsoluteUrl ,
83+ unencodedPathAndQuery ,
7484 CustomDataParameter ) ;
7585 output . Content . SetHtmlContent ( result . Html ) ;
7686
0 commit comments