I'm trying to send a base64 encoded data using a POST request and it contains the "+" char. When I send the request, the "+" is replaced with " " (space). Here goes the code
public string POST(string url, string query)
{
HttpWebRequest hwrq = CreateRequest(url);
hwrq.CookieContainer = Cookies;
hwrq.Method = "POST";
hwrq.ContentType = "application/x-www-form-urlencoded";
byte[] data = Encoding.Default.GetBytes(query);
hwrq.ContentLength = data.Length;
hwrq.GetRequestStream().Write(data, 0, data.Length);
using (HttpWebResponse hwrs = (HttpWebResponse)hwrq.GetResponse())
{
using (StreamReader sr = new StreamReader(hwrs.GetResponseStream()))
{
return sr.ReadToEnd().Trim();
}
}
}
开发者_JAVA百科 public HttpWebRequest CreateRequest(string url)
{
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(url);
Request.UserAgent = UserAgent;
Request.Accept = Accept;
Request.Headers.Add("Accept-Language", AcceptLang);
Request.AutomaticDecompression = DMethod;
return Request;
}
I've been tracking the "query" variable, it stays with the "+" char, but when I see the request in sniffer (Charles), the request is sent without the "+".
For example I'm trying to send<...>zxJ+zZq<...>
and
<...>zxJ zZq<...>
is actually sent.
What am I doing wrong? Thanks in advance.+
represents space in a query string. It looks like like your query
variable that you are sending is not properly URL encoded. Unfortunately you haven't shown how you are constructing this query
string variable but here's the correct way in order to ensure that all values are properly URL encoded:
var values = HttpUtility.ParseQueryString(string.Empty);
values["foo"] = "some + value";
values["bar"] = "some other value";
string query = values.ToString();
// query will equal foo=some+%2b+value&bar=some+other+value
Notice how the +
sign that was originally part of the value is encoded to %2B
.
If you write the following:
string query = "foo=some + value&bar=some other value";
I think you see the problem for yourself and the difference between the correct query string which is foo=some+%2b+value&bar=some+other+value
.
Now this being said here's what I would suggest you in order to improve your code. You could extend the WebClient
class so that it can handle cookies, like this:
public class WebClientEx : WebClient
{
public CookieContainer Cookies { get; private set; }
public WebClientEx()
{
Cookies = new CookieContainer();
}
protected override WebRequest GetWebRequest(Uri address)
{
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = Cookies;
return request;
}
}
and now simply:
using (var client = new WebClientEx())
{
client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0";
client.Headers[HttpRequestHeader.AcceptLanguage] = "en-us,en;q=0.5";
var values = new NameValueCollection
{
{ "foo", "some value" },
{ "bar", "some & other + value =" },
};
byte[] buffer = client.UploadValues("http://www.example.com", values);
string result = Encoding.UTF8.GetString(buffer);
}
See how much easier this is instead of messing around with all those HttpWebRequests, responses, streams, encodings, etc...?
The form data is sent URL encoded, and a space is encoded into a +, so a + will be decoded into a space.
Use the Server.UrlEncode method to encode the data that you want to send.
Try using a different content type:
hwrq.ContentType = "text/plain";
In your example you post raw base64 data (plain text), but you tell the remote server that you are posting a url encoded query string (application/x-www-form-urlencoded). That´s why the remote server tries to url decode your base64 data, which in turn will replace + with space.
精彩评论