Reputation: 23
I have an issue of using httpclient to post data to server.It works well of the httpClient.PostAsync with FormUrlEncodedContent.
However, if my content of FormUrlEncodedContent contains a charater of "~", it does not convert it as %7E. I have no idea how I can force it to encode it.
The following is my current example of the coding.
var content = new FormUrlEncodedContent(new Dictionary<string, string>()
{
["content"] = "Hello World~"
});
var response = await httpClient.PostAsync(url, content);
The Fiddler raw result of the body content will be:
content=Hello%20World~
It is not my expected. I expect the result should be content=Hello%20World%7E
How can I do that?
Thanks
Upvotes: 2
Views: 9897
Reputation: 4357
@gregkalapos and @Bertie have a wonderful answers.
But I have other way to encoding by use Uri.
Uri.EscapeDataString(str)
If you need unescape ,please use Uri.UnescapeDataString(str)
See:How to encode/decode url strings in an UWP App
Upvotes: 0
Reputation: 3619
This is interesting. So tilde (~) is very special… if you look at the rfc2396 and rfc3986 it is actually allowed in the URL. rfc1738 defined it as %7e, but rfc2396 and rfc3986 kind of overrule that.
So…this is basically dependent on the encoding implementation. For example PHP changed it at some point: http://php.net/manual/en/function.rawurlencode.php
Btw. in the CoreFx repo you can take a look at the source code of FormUrlEncodedContent
As you see it uses Uri.EscapeDataString
And it states that
By default, the EscapeDataString method converts all characters except for RFC 2396 unreserved characters to their hexadecimal representation.
And in RFC 2396 tilde is defined as an unreserved character.
So this works according to the documentation, and what fiddler shows you is an absolutely valid URL.
To your specific question to get %7e instead of '~': One option is to replace it manually, since this is really a special case.
Another one is to use System.Web.HttpUtility.UrlEncode, which encodes it to %7e. The difference between EscapeDataString (which is used by FormUrlEncodedContent) and System.Web.HttpUtility.UrlEncode is that EscapeDataString uses as many plaintext characters as possible. But both of them create a valid URL encoded string.
Upvotes: 4
Reputation: 2447
This is a work around that should do the job:
var formParams = new Dictionary<string, string>(){
["content"] = "Hello World~"
};
var stringFormParams = new Func<IDictionary<string,string>,string>((dic) => {
string result = "";
foreach(var param in dic) {
if (result.Length > 0) { result += "&"; }
result += param.Key + "=" + WebUtility.UrlEncode(param.Value);
}
return result;
}).Invoke(formParams);
var stringContent = new StringContent(stringFormParams, Encoding.UTF8, "application/x-www-form-urlencoded");
Console.WriteLine(stringContent.ReadAsStringAsync().Result);
HttpClient httpClient = new HttpClient();
var response = await httpClient.PostAsync(url, stringContent);
Output:
content=Hello+World%7E
Upvotes: 0
Reputation: 733
So you want to use the HttpUtility UrlEncode method, found in the "System.Web" library. See here for the msdn page.
System.Web.HttpUtility.UrlEncode(@"~\Hello World");
Result:
%7e%5cUrl%5cHello+World
I've tried and tested it - it correctly replaces the symbols with their correctly encoded counterpart.
Upvotes: 0