应如何构建 OData URI?

Joh*_*van 5 c# odata query-string querystringparameter uribuilder

我正在寻找构建 URI,例如https://example.com/data/customers?$top=100.

是否有UriBuilder用于创建 OData URI(即可以$适当处理诸如此类的字符)?

完整信息

我有这样的代码(简化示例):

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);
Run Code Online (Sandbox Code Playgroud)

但是,OData 特殊字符$会被编码为在 URI 中使用%24

我在 GitHub 上找到了OData.Net,它似乎是一个对此类事情有用的库,但它不是标准库的一部分,并且对于我的简单需求来说看起来相当重量级,所以我希望在致力于此之前找到更简单的东西OData.Net 路径...

当然,我可以通过做一个简单的操作来避免这种情况var uri = string.Join("/", new [] {rootUri, apiPath, entity, $"?$top={pageSize}"});......但我想确保我正在利用 .net 库的字符转义功能/而不是为框架已经提供给我的东西创建解决方案。

注意:我知道您可以从 OData 服务生成类,但我不想使用这种方法,因为这要求我在 API 更改时重新生成客户端代码(例如,将新字段添加到目标实体) 。相反,我想使用更“纯粹”的 HTTP 方法。

Joh*_*van 1

我找到了解决办法;我不需要特殊的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);
Run Code Online (Sandbox Code Playgroud)