首页 > 解决方案 > 正确访问 System.Net.Http.DelegatingHandler 中的查询参数

问题描述

给定一个HttpRequestMessage

调用提供System.Net.Http.HttpRequestMessageExtensionsGetQueryNameValuePairs()方法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(查询参数已被 URL 解码)。.RequestUrihttp://example.com/api/redirect?resource=aa9f2dcb-82f4-88dc-c716-dd71a1ac3802&type=x-application/x-share+json

解析调用之前或之后的编码或解码都不会起作用,因为/并且+由于某种原因在从 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 /is%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

当然不起作用,因为查询字符串的&s 现在已编码。

显然,某种形式的手动字符串解析(正则表达式等)会起作用。但是,这里的目标是使用标准库。

问题:虽然这已经在 Stack Overflow 的各个地方进行了解释,并且已经提供了一些解决方案,但据我所知,没有直接回答这个问题:Given an HttpRequestMessagein a DelegatingHandlerwhat is a correct/reliable way to access the使用内置库的未编码查询参数?

标签: c#.nethttpurlurl-routing

解决方案


推荐阅读