【问题标题】:Why are my query string parameters being url decoded twice? [duplicate]为什么我的查询字符串参数被 url 解码两次? [复制]
【发布时间】:2019-01-20 13:59:42
【问题描述】:

我有一个使用 .Net 4.7.1 的 web api,我注意到在其中一个端点上执行 get 时出现了一些奇怪的行为。当我对端点http://localhost:52684/api/v1/some-resource?client_timezone=%2B0500 执行获取时,参数客户端时区将作为" 0500" 而不是"+0500" 接收。我唯一能想到的是,Url 被解码了两次,所以"%2B" 变成了"+",然后是" "。有谁知道这种情况的任何常见原因或为什么会发生这种情况?

这是控制器上的一个类似端点

[HttpGet]
[Authorize]
[ApiRoute("some-resource", StartingVersion = 1)]
[EnableCors("*", "*", "GET", "*")]
public IHttpActionResult SomeResource([FromUri] string timezone)
{
    if (!DataValidationUtililties.IsValidClientTimezone(timezone))
    {
        return BadRequest();
    }
    return Ok();
}

【问题讨论】:

  • 您是否有示例说明您的代码中发生这种情况的位置?你能发布那个代码吗?
  • 我相信 + 被解释为一个空格。如果你用谷歌搜索“a b c”,则查询变为“google.co.uk/search?q=a+b+c&oq=a+b+c”,看看空格如何变成加号。
  • 是的,但我将 + 编码为 %2B
  • 它不是重复的我明确声明我在查询字符串中使用 %2B 最终变成一个空格。那篇文章说使用 %2B 而不是我正在做的查询字符串中的 +。
  • 我确实认为它是重复的,因为 Web API 对查询字符串和编码的+ 字符没有任何问题。您可能会在您编写的某些自定义过滤器中进行双重解码。

标签: c# .net asp.net-web-api urldecode


【解决方案1】:

我想我找到了原因。我创建了一个SnakeCaseActionSelector,它基本上重写了所有请求 URI。在这样做时,它会解码 url,并且永远不会再次编码查询字符串参数。

public class SnakeCaseActionSelector : ApiControllerActionSelector
{
    public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
    {
        var requestUri = controllerContext.Request.RequestUri;
        var queryPairs = controllerContext.Request.GetQueryNameValuePairs().ToList();
        if (!queryPairs.Any())
        {
            return base.SelectAction(controllerContext);
        }
        queryPairs = queryPairs.Select(x =>
                new KeyValuePair<string, string>(CamelCaseToSnakeCaseConverter.FromSnakeCase(x.Key), x.Value))
            .ToList();
        var newQueryParams = queryPairs.Select(x => $"{x.Key}={x.Value}").Aggregate((x, y) => x + "&" + y);
        var builder = new UriBuilder(requestUri)
        {
            Query = newQueryParams
        };
        controllerContext.Request.RequestUri = builder.Uri;

        return base.SelectAction(controllerContext);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多