Как вы должны построить OData URI? - PullRequest
0 голосов
/ 21 ноября 2018

Я ищу для создания URI, таких как https://example.com/data/customers?$top=100.

Существует ли UriBuilder для создания URI OData (то есть, который может обрабатывать такие символы, как $ соответственно)?

Полная информация

У меня есть такой код (упрощенный пример):

public Uri CreateMyApiUri(string rootUri, string apiPath, string entity, int pageSize)
{
    var builder = new UriBuilder(rootUri);
    builder.Path = ConcatPathParts(builder.Path, apiPath, entity); //basically string.Join("/", args), plus code to remove superfluous slashes
    var parameters = HttpUtility.ParseQueryString(builder.Query);
    if (pageSize > 0) parameters["$top"] = pageSize.ToString();
    builder.Query = parameters.ToString();
    return builder.Uri; 
}
//called like this
var uri = CreateMyApiUri("https://example.com", "data", "customers", 100);

Однако специальный символ OData $ кодируется для использования в URI как %24.

Я нашел OData.Net на GitHub, который кажется полезной библиотекой для таких вещей, но он не является частью стандартной библиотеки и выглядит достаточно тяжеловесно для моей простой потребности, поэтому я 'Я надеюсь найти что-то более простое, прежде чем идти по пути OData.Net ...

Конечно, я мог бы избежать этого, выполнив простой var uri = string.Join("/", new [] {rootUri, apiPath, entity, $"?$top={pageSize}"}); ... но я хочу убедиться, что я 'Я пользуюсь преимуществами символов библиотеки .net, избегая функций / не создавая решения для чего-то, что инфраструктура уже дает мне.

NB: я знаю, что вы можете генерировать классы из сервисов OData, но я неЯ хочу использовать этот подход, так как он требует, чтобы я перегенерировал клиентский код, если API изменен (например, новые поля добавлены в целевую сущность).Вместо этого я хочу использовать более «чистый» подход HTTP.

1 Ответ

0 голосов
/ 22 ноября 2018

Я нашел решение;Мне не нужно было особенное ODataUriBuilder;скорее была ошибка в моем использовании query.ToString(), как объяснено здесь: https://stackoverflow.com/a/26789977/361842

Применение этого исправления к приведенному выше коду решает проблему:

public Uri CreateMyApiUri(string rootUri, string apiPath, string entity, int pageSize)
{
    var builder = new UriBuilder(rootUri);
    builder.Path = ConcatPathParts(builder.Path, apiPath, entity); //basically string.Join("/", args), plus code to remove superfluous slashes
    var parameters = HttpUtility.ParseQueryString(builder.Query);
    if (pageSize > 0) parameters["$top"] = pageSize.ToString();

    //the fix:
    builder.Query = Uri.EscapeUriString(HttpUtility.UrlDecode(parameters.ToString()));
    //instead of:
    //builder.Query = parameters.ToString();

    return builder.Uri; 
}
//called like this
var uri = CreateMyApiUri("https://example.com", "data", "customers", 100);
...