6

我使用 Refit for RestAPI。我需要创建相同的查询字符串api/item?c[]=14&c[]=74

在改装界面中我创建了方法

[Get("/item")]
Task<TendersResponse> GetTenders([AliasAs("c")]List<string> categories=null);

并创建 CustomParameterFormatter

string query = string.Join("&c[]=", values);

CustomParameterFormatter 生成的字符串14&c[]=74

但是重新调整编码参数和生成的urlapi/item?c%5B%5D=14%26c%5B%5D%3D74

如何禁用此功能?

4

2 回答 2

5

首先,您的 api 服务器是否能够解析以下内容? api/item?c%5B%5D=14%26c%5B%5D%3D74

编码非常适合避免向服务器注入代码。

这是Refit有点固执己见的事情,即 uri 应该被编码,服务器应该被升级以读取编码的 uri。

但这显然应该是 Refit 中的可选设置,事实并非如此。

因此,您目前可以通过使用 DelegatingHandler 来做到这一点:

/// <summary>
/// Makes sure the query string of an <see cref="System.Uri"/>
/// </summary>
public class UriQueryUnescapingHandler : DelegatingHandler
{   
    public UriQueryUnescapingHandler()
        : base(new HttpClientHandler()) { }
    public UriQueryUnescapingHandler(HttpMessageHandler innerHandler)
        : base(innerHandler)
    { }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var uri = request.RequestUri;
        //You could also simply unescape the whole uri.OriginalString
        //but i don´t recommend that, i.e only fix what´s broken
        var unescapedQuery = Uri.UnescapeDataString(uri.Query);

        var userInfo = string.IsNullOrWhiteSpace(uri.UserInfo) ? "" : $"{uri.UserInfo}@";
        var scheme = string.IsNullOrWhiteSpace(uri.Scheme) ? "" : $"{uri.Scheme}://";

        request.RequestUri = new Uri($"{scheme}{userInfo}{uri.Authority}{uri.AbsolutePath}{unescapedQuery}{uri.Fragment}");
        return base.SendAsync(request, cancellationToken);
    }
}


Refit.RestService.For<IYourService>(new HttpClient(new UriQueryUnescapingHandler()))
于 2016-11-26T19:29:02.870 回答
1

对于任何偶然发现这个老问题的人,您可以使用 [QueryUriFormat(UriFormat.Unescaped)]属性。

于 2021-09-20T10:52:23.353 回答