给出,一个HttpRequestMessage
,
System.Net.Http.DelegatingHandler
的{{1}}方法拦截SendAsync
的结果在提供的http://example.com/api/redirect?resource=aa9f2dcb-82f4-88dc-c716-dd71a1ac3802&type=x-application%2fx-share%2bjson
上调用System.Net.Http.HttpRequestMessageExtensions
的{{1}}方法将为GetQueryNameValuePairs()
产生一个损坏的值。
request
说明
type
的{{1}}属性值为public class MyHandler : System.Net.Http.DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var typeStr = request.GetQueryNameValuePairs().Skip(1).First().Value;
// fails . "x-application/share json" == typeStr
Assert.IsTrue("x-application/share+json", typeStr);
}
}
(查询参数已被URL解码)。
在解析调用之前或之后进行编码或解码都不起作用,因为从ASP.NET API传入时,HttpRequestMessage
和.RequestUri
由于某种原因处于不同的“编码状态”。使用http://example.com/api/redirect?resource=aa9f2dcb-82f4-88dc-c716-dd71a1ac3802&type=x-application/x-share+json
解析URL并调用/
可以提示这是一个问题。
+
请注意,在HttpUtility
中,queryValues.ToString()
是var queryValues = HttpUtility.ParseQueryString(request.RequestUri.Query);
queryValues.ToString() == "resource=aa9f2dcb-82f4-88dc-c716-dd71a1ac3802&type=x-application%2fx-share+json"
,而type=x-application%2fx-share+json
仍然是/
(不同的“编码状态”)。
替代
对结果值进行网址解码会重新插入%2f
,但会将+
转换为+
。
+
在调用/
之前对查询字符串进行网址编码
%2f
当然不起作用,因为查询字符串的var urlEncodedResult = HttpUtility.UrlEncode(typeString);
// urlEncodedResult == "x-application%2fx-share+json"
已被编码。
很显然,某些形式的手动字符串解析(正则表达式等)将起作用。但是,这里的目标是使用标准库。
问题:尽管已经在Stack Overflow的不同地方对此进行了解释,并提供了一些解决方案,但据我所知,并没有直接回答问题: Given HttpUtility.ParseQueryString
中的var urlEncodedQuery = HttpUtility.UrlEncode(uri.Query);
// urlEncodedQuery == %3fresource%3daa9f2dcb-82f4-88dc-c716-dd71a1ac3802%26type%3dx-application%2fx-share%2bjson
HttpUtility.ParseQueryString(urlEncodedQuery)["type"] // null
是什么?使用内置库访问未编码查询参数的正确/可靠方法是什么?