How to escape URL-encoded data in POST with HttpWebRequest - c#

I am trying to send an URL-encoded post to a REST API implemented in PHP. The POST data contains two user-provided strings:
WebRequest request = HttpWebRequest.Create(new Uri(serverUri, "rest"));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.Headers.Add("Content-Transfer-Encoding", "binary");
// Form the url-encoded credentials we'll use to log in
StringBuilder builder = new StringBuilder();
builder.Append("user=");
builder.Append(user);
builder.Append("&password=");
builder.Append(password);
byte[] credentials = Encoding.UTF8.GetBytes(builder.ToString());
// Write the url-encoded post data into the request stream.
request.ContentLength = credentials.Length;
using (Stream requestStream = request.GetRequestStream()) {
requestStream.Write(credentials, 0, credentials.Length);
}
This sends a HTTP request to the server containing user=myusername&password=mypassword in UTF-8 as its POST data.
How can I escape the user-provided strings?
For example, if I had a user named big&mean, how should the ampersand be escaped so that it does not mess up the request line?

You can use the static HttpUtility class in System.Web for encoding and decoding HTML and Url related values.
Try HttpUtility.UrlEncode().

It would seem that System.Web is obsolete - the newer way to access it is System.Net.WebUtility.HtmlEncode

Related

How to load webview with post parameters in windows 8?

I need to load website using webview in metro apps. I could post login parameters using following method. how to load the same in webview??????
string post_data = "userName=test123&password=test#321";
// this is where we will send it
string uri = "http://tesproject.com";
// create a request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.UTF8.GetBytes(post_data);
// this is important - make sure you specify type this way
request.ContentType = "application/x-www-form-urlencoded";
Stream requestStream = await request.GetRequestStreamAsync();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
// grab te response and print it out to the console along with the status code
WebResponse response = await request.GetResponseAsync();
WebView class doesn't support navigating to an URL with POST parameters directly.
You could however use your code and the WebResponse to get the HTML. And then use the NavigateToString method of the WebView class to render the HTML:
HttpWebResponse httpResponse= (HttpWebResponse)response;
StreamReader reader=new StreamReader(httpResponse.GetResponseStream());
string htmlString= reader.ReadToEnd();
if (!string.IsNullOrEmpty(htmlString))
webView.NavigateToString(htmlString);
Or you could create your own HTML with a form with your post values and some javascript to submit the form, but that might be a bit more cumbersome.

google api oauth access token retrieval - 400 bad request

I'm trying to retrieve the oauth access token to make calls to some google apis in asp.net mvc, and I wrote the following code for an action:
public ActionResult GetOAuthToken()
{
String url = "https://accounts.google.com/o/oauth2/token";
// Create a request using a URL that can receive a post.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
// Set the Method property of the request to POST.
request.Method = "POST";
request.Host = "accounts.google.com";
// Create POST data and convert it to a byte array.
string postData = String.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code", Request.QueryString["code"].ToString(), OAuthConfig.client_id, OAuthConfig.client_secret, OAuthConfig.token_redirect_uri);
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byteArray = encoding.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// SOME CODE TO PROCESS THE RESPONSE
Response.Redirect("/Home");
return View();
}
OAuthConfig is just a class that contains the client id, client secret etc.
I keep getting 'The remote server returned an error: (400) Bad Request.' at the request.GetResponse() line. Where am I going wrong?
Google does provide a higher level library to work with its services, this handles the formatting of the urls and I find it makes it a lot easier to work with their apis. See http://code.google.com/p/google-api-dotnet-client/

C# HttpWebRequest POST => !! Unexpected error while processing request: invalid %-encoding

i am facing a problem where i try to communicate with a Ruby API from a C# application.
I need to POST some JSON data, with the parameter name "data" but the API return me: '!! Unexpected error while processing request: invalid %-encoding'.
I tried with Content-Type set to 'application/json' and 'application/x-www-form-urlencoded; charset=utf-8'.
My POST data look like this 'data=some_json_string'.
I figure i should escape the json string, so if it is my problem, how to do it with .NET without using a 3rd party library?
Code:
byte[] data = System.Text.ASCIIEncoding.UTF8.GetBytes(sdata);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.Absolute));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
request.ContentLength = data.Length;
Stream reqStream = request.GetRequestStream();
// Send the data.
reqStream.Write(data, 0, data.Length);
reqStream.Close();
Thanks in advance!
Presuming the string sdata coming in is already in JSON format you could do:
using (WebClient wc = new WebClient())
{
string uri = "http://www.somewhere.com/somemethod";
string parameters = "data=" + Uri.EscapeDataString(sdata);
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string result = wc.UploadString(uri, parameters);
}
Depending on the consuming service it may need the Content-type set to application/json?

C# Escape Plus Sign (+) in POST using HttpWebRequest

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.
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.
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);
}
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,

C# web request with POST encoding question

On the MSDN site there is an example of some C# code that shows how to make a web request with POST'ed data. Here is an excerpt of that code:
WebRequest request = WebRequest.Create ("http://www.contoso.com/PostAccepter.aspx ");
request.Method = "POST";
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes (postData); // (*)
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream ();
dataStream.Write (byteArray, 0, byteArray.Length);
dataStream.Close ();
WebResponse response = request.GetResponse ();
...more...
The line marked (*) is the line that puzzles me. Shouldn't the data be encoded using the UrlEncode method rather than UTF8? Isn't that what application/x-www-form-urlencoded implies?
The sample code is misleading, because ContentType is set to application/x-www-form-urlencoded but the actual content is plain text. application/x-www-form-urlencoded is a string like this:
name1=value1&name2=value2
The UrlEncode function is used to escape especial characters like '&' and '=' so a parser doesn't consider them as syntax. It takes a string (media type text/plain) and returns a string (media type application/x-www-form-urlencoded).
Encoding.UTF8.GetBytes is used to convert the string (media type application/x-www-form-urlencoded in our case) into an array of bytes, which is what the WebRequest API expects.
As Max Toro indicated, the examples on the MSDN site are incorrect: a correct form POST requires the data to be URL encoded; since the data in the MSDN example does not contain any characters that would be changed by encoding, they are, in a sense, already encoded.
The correct code would have a System.Web.HttpUtility.UrlEncode call on the names and values of each name/value pair before combining them into the name1=value1&name2=value2 string.
This page was helpful: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx

Categories

Resources