Дано , HttpRequestMessage
,
Вызов метода System.Net.Http.HttpRequestMessageExtensions
GetQueryNameValuePairs()
для указанного request
приведет к неправильному значению для type
.
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);
}
}
Объяснение
Значение свойства HttpRequestMessage
.RequestUri
равно http://example.com/api/redirect?resource=aa9f2dcb-82f4-88dc-c716-dd71a1ac3802&type=x-application/x-share+json
(параметры запроса были декодированы URL).
Ни кодирование, ни декодирование до или после вызова синтаксического анализа не будут работать, поскольку /
и +
по какой-то причине находятся в разных «состояниях кодирования» при передаче из ASP.NET API. Использование HttpUtility
для анализа URL-адреса и вызов 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
, а +
равно +
(различные "состояния кодирования").
Альтернатива
Url, декодирующий полученное значение, повторно вставляет +
, но преобразует /
в %2f
.
var urlEncodedResult = HttpUtility.UrlEncode(typeString);
// urlEncodedResult == "x-application%2fx-share+json"
URL, кодирующий строку запроса перед вызовом 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
, конечно, не работает, потому что строки запроса &
теперь закодированы.
Очевидно, что какая-то форма ручного анализа строк (регулярное выражение и т. Д.) Будет работать. Однако цель здесь состоит в том, чтобы использовать стандартные библиотеки.
Вопрос : Хотя это было объяснено в различных местах по переполнению стека, и были предложены некоторые решения, насколько мне известно, прямого ответа на вопрос нет: Учитывая HttpRequestMessage
в DelegatingHandler
, как правильно / надежно получить доступ к некодированным параметрам запроса с помощью встроенных библиотек?