c# - 为什么我的查询字符串参数被 url 解码两次?

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

<分区>

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

Controller 上有一个类似的端点

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

最佳答案

我想我找到了原因。我创建了一个 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);
    }
}

关于c# - 为什么我的查询字符串参数被 url 解码两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51829093/

相关文章:

c# - API 路由 : Multiple operations with path

session - ASP.NET Web API session 还是其他什么?

c# - IQueryable 和 IEnumerable 之间区别的真实示例?

c# - 将 xml 存储在已编译的 DLL 中

c# - 微软消息队列和资源发布最佳实践

c# - 检测已安装的浏览器,因此 Process.Start ("chrome") 不会出错

c# - 带有异步 Task.Run 方法的死锁,带有来自 Synchronus 方法的 Wait 和超时

c# - 自定义 Web api 帮助页面以删除请求格式

c# - 将 IDictionary<T, Task<bool>> 转换为 IObservable<KeyValuePair<T, bool>>

mysql - 计算两个日期之间的可用房间数量