RestSharp codifica espaços em parâmetros de formulário no corpo como %20
, +
, ou nada, dependendo da preferência do usuário.
RestSharp codifica espaços em parâmetros de formulário no corpo como +
.
" "
) com um caractere de adição ( "+"
)Estamos chamando uma API de terceiros que exige que um valor de parâmetro seja separado por espaços (por exemplo VALUE1 VALUE2 VALUE3
, codificado: param=VALUE1%20VALUE2%20VALUE3
). Ao usar RestSharp, o comportamento de Uri.EscapeDataString()
e HttpUtility.UrlEncode
é diferente:
Uri.EscapeDataString("ABC DEF")
> ABC%20DEF
HttpUtility.UrlEncode("ABC DEF")
> ABC+DEF
RestSharp deve suportar alguma forma de customização nesta parte, ou permitir que o usuário implemente sua própria função (opcional) de escape / codificação / sanitização para substituir o comportamento padrão.
A especificação HTTP application/x-www-form-urlencoded menciona que os espaços devem ser codificados como +
, no entanto %20
também segue a especificação e nem todos os sistemas de terceiros aceitam +
como substituto de um caractere de espaço, independentemente da especificação.
NB Existe uma solução para isso para codificar o corpo do formulário como param=ABC%20DEF
?
Seria bom se você também pudesse apresentar uma sugestão para que isso seja corrigido ou um pull request.
Acabei de encontrar isso também, quebrando em uma API que aceita apenas '%20' e não '+' para parâmetros GET em uma chamada REST, mas a causa raiz é idêntica.
A solução óbvia seria permitir algum tipo de maneira de substituir o comportamento de EncodeParameter
para permitir o uso de EscapeDataString
em vez de UrlEncode
Existem vários tópicos extensos sobre estouro de pilha (por exemplo, https://stackoverflow.com/questions/602642/server-urlencode-vs-httputility-urlencode) sobre isso, mas não está claro qual é o comportamento correto. e seria muito conveniente ter alguma maneira de escolher o que você precisa, em vez de sempre usar UrlEncode
, o que definitivamente não é o comportamento correto em alguns casos.
Como solução alternativa, basicamente, não use nada que defina Parameters
e faça isso manualmente.
Estou pensando na melhor maneira de implementar isso ... provavelmente uma interface IParameterEncoder
com um DefaultParameterEncoder
que chama HttpUtility.UrlEncode(...)
que é definido como a implementação padrão, mas pode ser substituído em algum lugar. Faz sentido colocá-lo em RestClient
, ou deveria ir em Http
como onde está a propriedade IWebProxy
, aqui?
Acho que seria mais fácil fazer assim:
public Func<string, string> Encoder { get; set; } = s => HttpUtility.UrlEncode(s);
Não sinto necessidade de uma interface para uma única função.
@qJake assim
https://github.com/restsharp/RestSharp/commit/62e95bd03a0c64ac3933b648be4ee18d6c220ad7#diff -fbb0205ba27639004072c041141c4459R133
/// <summary>
/// Allows to use a custom way to encode parameters
/// </summary>
/// <param name="encoder">A delegate to encode parameters</param>
/// <example>client.UseUrlEncoder(s => HttpUtility.UrlEncode(s));</example>
/// <returns></returns>
public IRestClient UseUrlEncoder(Func<string, string> encoder)
{
Encode = encoder;
return this;
}
@alexeyzimarev Sim! Isso seria fantástico. 👍
Será lançado na próxima versão.