0

I'm having issues to send POST data that includes characteres like "+" in the password field,

string postData = String.Format("username={0}&password={1}", "anyname", "+13Gt2");

I'm using HttpWebRequest and a webbrowser to see the results, and when I try to log in from my C# WinForms using HttpWebRequest to POST data to the website, it tells me that password is incorrect. (in the source code[richTexbox1] and the webBrowser1). Trying it with another account of mine, that does not contain '+' character, it lets me log in correctly (using array of bytes and writing it to the stream)

byte[] byteArray = Encoding.ASCII.GetBytes(postData); //get the data
request.Method = "POST"; 
request.Accept = "text/html";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
newStream.Close(); //this works well if user does not includes symbols

From this Question I found that HttpUtility.UrlEncode() is the solution to escape illegal characters, but I can't find out how to use it correctly, my question is, after url-encoding my POST data with urlEncode() how do I send the data to my request correctly?

This is how I've been trying for HOURS to make it work, but no luck,

First method

string urlEncoded = HttpUtility.UrlEncode(postData, ASCIIEncoding.ASCII);
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = urlEncoded.Length;
StreamWriter wr = new StreamWriter(request.GetRequestStream(),ASCIIEncoding.ASCII);
wr.Write(urlEncoded); //server returns for wrong password.
wr.Close();

Second method

byte[] urlEncodedArray = HttpUtility.UrlEncodeToBytes(postData,ASCIIEncoding.ASCII);
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(urlEncodedArray, 0, urlEncodedArray.Length); // Send the data.
newStream.Close();  //The server tells me the same thing..

I think I'm doing wrong on how the url-encoded must be sent to the request, I really ask for some help please, I searched through google and couldn't find more info about how to send encoded url to an HttpWebRequest.. I appreciate your time and attention, hope you can help me. Thank you.

Community
  • 1
  • 1
WhySoSerious
  • 1,930
  • 18
  • 18
  • You dont have to encode post data. In fact, when you encode post data like this, the browser will interpret it wrongly. You probably have a problem with your encoding. Add charset=ISO-8859-1 to your content type and see what happens – Polity Dec 15 '11 at 09:13
  • @Polity First thank you for making it clear for me, I couldn't find how to use the urlEncode to escape special characters, I tried what you told me (charset=ISO-8859-1) and still have same results, nothing changed, I believe it's on the encoding, the '+' is converted to a space. – WhySoSerious Dec 17 '11 at 03:05

3 Answers3

6

I found my answer using Uri.EscapeDataString it exactly solved my problem, but somehow I couldn't do it with HttpUtility.UrlEncode. Stackoverflowing around, I found this question that is about urlEncode method, in msdn it documentation tells that:

Encodes a URL string.

But I know now that is wrong if used to encode POST data (@Marvin, @Polity, thanks for the correction). After discarding it, I tried the following:

string postData = String.Format("username={0}&password={1}", "anyname", Uri.EscapeDataString("+13Gt2"));

The POST data is converted into:

// **Output
string username = anyname;
string password = %2B13Gt2;

Uri.EscapeDataString in msdn says the following:

Converts a string to its escaped representation.

I think this what I was looking for, when I tried the above, I could POST correctly whenever there's data including the '+' characters in the formdata, but somehow there's much to learn about them.

This link is really helpful.

http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx

Thanks a lot for the answers and your time, I appreciate it very much. Regards mates.

Community
  • 1
  • 1
WhySoSerious
  • 1,930
  • 18
  • 18
5

I'd recommend you a WebClient. Will shorten your code and take care of encoding and stuff:

using (var client = new WebClient())
{
    var values = new NameValueCollection
    { 
        { "username", "anyname" },
        { "password", "+13Gt2" },
    };
    var url = "http://foo.com";
    var result = client.UploadValues(url, values);
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks @Darin, but unfortunately the website does not support WebClient, so anytime I do this, I get "this browser is not supported" However is interesting how it is not needed to set encoding when using WebClient, but I'll try if this works when passing a '+' character. I already found my answer using `Uri.EscapeDataString` Thanks a lot for the useful answer. – WhySoSerious Dec 17 '11 at 03:17
  • 4
    @WhySoSerious, a web site doesn't know what a WebClient is. A web site listens and answers HTTP requests. A WebClient can send HTTP requests. So if the site says that the browser is not supported chances are that this site expects some special User-Agent header to be set in the request. So simply use the Headers property and set the User-Agent HTTP request header to whatever the site you are trying to reach expects. – Darin Dimitrov Dec 17 '11 at 11:13
-1

the postdata you are sending should NOT be URL encoded! it's formdata, not the URL

  string url = @"http://localhost/WebApp/AddService.asmx/Add";
  string postData = "x=6&y=8";

  WebRequest req = WebRequest.Create(url);
  HttpWebRequest httpReq = (HttpWebRequest)req;

  httpReq.Method = WebRequestMethods.Http.Post;
  httpReq.ContentType = "application/x-www-form-urlencoded";
  Stream s = httpReq.GetRequestStream();
  StreamWriter sw = new StreamWriter(s,Encoding.ASCII);
  sw.Write(postData);
  sw.Close();

  HttpWebResponse httpResp = 
                 (HttpWebResponse)httpReq.GetResponse();
  s = httpResp.GetResponseStream();
  StreamReader sr = new StreamReader(s, Encoding.ASCII);
  Console.WriteLine(sr.ReadToEnd());

This uses the System.Text.Encoding.ASCII to encode the postdata.

Hope this helps,

Marvin Smit
  • 4,088
  • 1
  • 22
  • 21
  • This either wont fix the problem or introduces more bugs. See: http://www.w3.org/TR/REC-html40/charset.html#h-5.2.2 there is no implied encoding in HTML and HTTP implies ISO-8859-1 as the default encoding, not ASCII (which isnt even an encoding in the first place, ask skeet ;)) – Polity Dec 15 '11 at 09:23
  • Hi @Marvin, thanks for the answer but this is what I did on my code, and this still does not escape '+' character, see that I used it with the `StreamWriter` with the ASCII encoding when trying to "encode" the postData, which is wrong (knowing it from you guys), thanks for your time to answer. – WhySoSerious Dec 17 '11 at 03:23