RestSharp encodes spaces in form parameters in the body as %20
, +
, or not at all, depending on user preference.
RestSharp encodes spaces in form parameters in the body as +
.
" "
) with a plus character ("+"
)We are calling a third party API that requires a parameter value to be separated by spaces (e.g. VALUE1 VALUE2 VALUE3
, encoded: param=VALUE1%20VALUE2%20VALUE3
). When using RestSharp, the behavior of Uri.EscapeDataString()
and HttpUtility.UrlEncode
differs:
Uri.EscapeDataString("ABC DEF")
> ABC%20DEF
HttpUtility.UrlEncode("ABC DEF")
> ABC+DEF
RestSharp should support some manner of customization on this part, or allow the user to implement their own (optional) escape / encode / sanitize function in order to override the default behavior.
The HTTP application/x-www-form-urlencoded spec does mention that spaces should be encoded as +
, however %20
also follows the spec, and not all third party systems accept +
as a substitute for a space character regardless of the spec.
N.B. Is there a workaround to this in order to encode the form body as param=ABC%20DEF
?
It would be nice if you also can come up with a suggestion for this to be fixed, or a pull request.
I just encountered this as well, breaking against an API that only accepts '%20' not '+' for GET params on a REST call, but the root cause is identical.
The obvious solution would be to allow some kind of way to override the behavior of EncodeParameter
to allow the use of EscapeDataString
instead of UrlEncode
There are a number of extensive threads on stack overflow (eg https://stackoverflow.com/questions/602642/server-urlencode-vs-httputility-urlencode) about this, but it is ultimately unclear what the correct behavior actually is... and it would be very convenient to have some way to pick what you need, rather than always using UrlEncode
, which is definitely not the correct behavior in some cases.
As a workaround, basically, don't use anything that set Parameters
, and do it manually.
I'm thnking about the best way to implement this... probably an IParameterEncoder
interface with a DefaultParameterEncoder
that calls HttpUtility.UrlEncode(...)
which is set as the default implementation, but can be overridden somewhere. Does it make sense to put it in RestClient
, or should it go in Http
like where the IWebProxy
property is, here?
I think it would be easier to have it like this:
public Func<string, string> Encoder { get; set; } = s => HttpUtility.UrlEncode(s);
I don't feel a need for an interface for a single function.
@qJake like this
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 Yes! That would be fantastic. 馃憤
Will be released in the next version.