【问题标题】:How to make Webapi GET method work with reserved characters on query param?如何使 Web Api GET 方法与查询参数上的保留字符一起使用?
【发布时间】:2020-01-23 19:12:56
【问题描述】:

我有一个非常简单的 web 服务,它带有一个带有令牌字符串参数的 GET 方法。我使用这个标记可以有字母,“+”和“/”。例如:mC1SW7RJhgsQGtRHhsg/Q+FGoZjbBleNKtpqT7zLMtE

如果有这个令牌的数据,我使用这个令牌在数据库中查找。

我在控制器中的方法是这样的:

[HttpGet("{token}")]
[ProducesResponseType(typeof(string), 200)]
[ProducesResponseType(typeof(void), 404)]
public JsonResult Get(string token)
{
    string sql = "SELECT dataObject FROM Session WHERE id = @SessionToken";
    var data = _conn.QueryFirstOrDefault<Session>(sql, new {SessionToken = token});
    if (data == null){
        var r = Json(string.Empty);
        r.StatusCode = StatusCodes.Status404NotFound;
        return r;
    }
    else {
        return Json(JsonConvert.DeserializeObject(data.dataObject));
    }
}

我看到 Dapper/Webapi 自动转义了这个参数,例如将“/”更改为“%2F”。

当我部署它时,它只适用于没有特殊字符的令牌并返回 404。

作为一种解决方法,我更改了服务器中的令牌以对令牌进行编码并将编码的加号替换为空格:

string decodedToken = WebUtility.UrlDecode(token);
token = decodedToken.Replace(" ", "+");

问题是我需要我的客户做相反的事情并替换“+”号:

var encodedToken = WebUtility.UrlEncode(token);
// Convert '+' to ' '
token = encodedToken.Replace("%2B", " ");

在不要求客户替换 de '+' 符号的情况下,推荐的工作方式是什么?

【问题讨论】:

标签: rest asp.net-core iis asp.net-core-webapi


【解决方案1】:

出于某种原因,Kestrel 或 .NET MVC 在编码的 URL 中进行部分解码。这看起来像一个 BUG (https://github.com/aspnet/Mvc/issues/6388),但有一个解决方法。

使用您传递的令牌,您可以在客户端对其进行编码:

 Original Token: mC1SW7RJhgsQGtRHhsg/Q+FGoZjbBleNKtpqT7zLMtE   
 Encoded Token: mC1SW7RJhgsQGtRHhsg%2FQ%2BFGoZjbBleNKtpqT7zLMtE

看到“/”变成了“%2F”,“+”变成了“%2B”。这是因为这两个字符是组成 URL 的一部分。因此,要将它们完全传递给 WebApi,必须将它们替换为它们的 ASCII 表示形式。

您可以使用这样的编码令牌调用您的服务:

 http://myserver:1234/myservice/token/mC1SW7RJhgsQGtRHhsg%2FQ%2BFGoZjbBleNKtpqT7zLMtE

在您的服务中,由于该错误,您将从 Kestrel/MVC 收到以下部分解码的字符串:

 Partially decoded token: mC1SW7RJhgsQGtRHhsg%2FQ+FGoZjbBleNKtpqT7zLMtE

只需实现一个简单的替换:

 token.Replace("%2F", "/");

您的字符串将被完整解码。

【讨论】:

    【解决方案2】:

    尝试在您的web.config 中添加以下代码:

    <system.webServer>
       <security>
          <requestFiltering allowDoubleEscaping="true" />
       </security>
    </system.webServer>
    

    参考Dotnet core + (plus) sign in Web API routing

    【讨论】:

    • 是dotnetcore。这不适用。
    • @StaticX 这个链接是asp.net core发布到IIS的,你试过吗?
    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 2012-03-06
    • 2021-10-21
    • 1970-01-01
    • 2013-07-18
    • 2021-01-05
    相关资源
    最近更新 更多