Как заставить метод Webapi GET работать с зарезервированными символами в параметре запроса? - PullRequest
1 голос
/ 23 сентября 2019

У меня очень простой веб-сервис с одним методом 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", " ");

Каков рекомендуемый способ работы, не требуя от клиента замены знаков «+»?

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

По какой-то причине Kestrel или .NET MVC выполняют частичное декодирование в закодированном URL.Это похоже на ошибку (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", "/");

И ваша строка будет полностью декодирована.

0 голосов
/ 24 сентября 2019

Попробуйте добавить следующий код в web.config:

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

См. Ядро Dotnet + (плюс) знак в маршрутизации Web API

...