WebRequest POST long value? - c#

I have a string with 300 rows, there is a way to do it POST?
Here is my code, is currently working on a limited amount of short letters:
WebRequest req = (HttpWebRequest)WebRequest.Create(
"http://thisisurl/test.php?ad=test&f=" + information_data);
req.Method = "POST";
WebResponse res = req.GetResponse();

I'm going to explain your problem right now and go ahead and give you a possible solution at the end.
You are hitting the character limit for url length / query parameter length. IE limits it as low as 2,083.
The data you are providing should be sent in the body of the http request, not the URL parameters.
A Post Request Normally is done in the following format(Code from the link).
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["username"] = "myUser";
data["password"] = "myPassword";
var response = wb.UploadValues(url, "POST", data);
}
This thread should have enough info if you want to use the WebRequest class instead:
HTTP request with post

Related

HttpWebResponse contentLength always -1

My web response content length always seem to be -1 after my web request. I'm sure you massage and signature are right.
What am I doing wrong here?
string msg = string.Format("{0}{1}{2}", nonce, clientId, apiKey);
string signature = ByteArrayToString(SignHMACSHA256(apiSecret, StrinToByteArray(msg))).ToUpper();
const string endpoint = "https://www.bitstamp.net/api/balance/";
HttpWebRequest request = WebRequest.Create(endpoint) as HttpWebRequest;
request.Proxy = null;
request.Method = "POST";
request.ContentType = "application/xml";
request.Accept = "application/xml";
request.Headers.Add("key", apiKey);
request.Headers.Add("signature", signature);
request.Headers.Add("nonce", nonce.ToString());
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
From the documentation,
The ContentLength property contains the value of the Content-Length header returned with the response. If the Content-Length header is not set in the response, ContentLength is set to the value -1.
Got it working with webClient instead of the httpWebRequest.
If someone can get it working with httpWebRequest, you wil get the answer.
string msg = string.Format("{0}{1}{2}", nonce, clientId, apiKey);
var signature = ByteArrayToString(SignHMACSHA256(apiSecret, StrinToByteArray(msg))).ToUpper();
var path = "https://www.bitstamp.net/api/user_transactions/";
using (WebClient client = new WebClient())
{
byte[] response = client.UploadValues(path, new NameValueCollection()
{
{ "key", apiKey },
{ "signature", signature },
{ "nonce", nonce.ToString()},
});
var str = System.Text.Encoding.Default.GetString(response);
}
Because this worked with 'WebClient', there was nothing wrong with the request, which means almost definitely that the request was being sent back 'Chunked'. This is indicated by the header 'Transfer-Encoding'.
There are several reasons why the webserver might send back something chunked including the fact that the return is binary.
I came to this page because Fiddler was "interfering" with my request by turning a perfectly good response by the server and then returning it chunked to my client. That was because I had the 'Stream' button pushed or active. When it isn't, it sends the data back buffered which preserves the response from the server. That was a horrible thing to track down..
But the research did tell me about why the Content-Length header might be -1.
The solution? Either fix the way the server (or proxy in my case) is sending the response back, or just read the response stream to the end. The latter will return all the chunks to you connected and you can take a length of the bytes returned.
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
String responseString = reader.ReadToEnd();
int responseLength = responseString.Length;
If you want bytes it is more involved -- not sure if there is a reader that allows you to read to the end -- the Binary reader requires a buffer up front.
An elegant way to consume (all bytes of a) BinaryReader?
Njoy.

Internal server with MTGOX api

I have a problem calling the MTGox HTTP api v2.
I wrote a sendrequest function to generally handle all my requests.
It works great for MONEY/INFO or MONEY/ORDERS but I get a 500 internal server error when i try methods MONEY/ORDER/QUOTE or MONEY/ORDER/ADD.
It seems like when the post_data contains anything besides the nonce, it goes wrong.
What do I have to do to solve this?
The sendrequest function:
private string sendRequest(string action, NameValueCollection query)
{
NameValueCollection nvc = new NameValueCollection();
nvc.Add("nonce", DateTime.Now.Ticks.ToString());
nvc.Add(query);
String post_data = "";
for (int i = 0; i < nvc.Count; i++)
{
post_data += "&";
post_data += nvc.Keys[i];
post_data += "=";
post_data += nvc[i];
}
post_data = post_data.Substring(1);
action = "BTCEUR/money/" + action;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sBasePath + action);
action += "\0"+post_data;
req.Method = "POST";
HMACSHA512 hmac = new HMACSHA512(GetBytes(action));
hmac.Key = Convert.FromBase64String(secret);
String sign = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(action)), Base64FormattingOptions.None);
req.Headers.Add("Rest-Key", apikey);
req.Headers.Add("Rest-Sign", sign);
req.UserAgent = "Mozilla/4.0 (compatible; MtGoxTradeCLI)";
req.ContentType = "application/x-www-form-urlencoded";
StreamWriter reqStream = new StreamWriter(req.GetRequestStream());
reqStream.Write(post_data);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader respStream = new StreamReader(resp.GetResponseStream());
String response = respStream.ReadToEnd();
respStream.Close();
return response;
}
Make sure the nonce in your signature comes last in your signature for any request that takes params, e.g. for money/wallet/history with currency USD your signature should be:
money/wallet/history\0currency=USD&nonce=xxxxxxxxxx
(the \0 is a null character, just in case you're wondering)
Also, MtGox's API seems to be in flux right now - for example, for wallet history above, we used to call:
BTCUSD/money/wallet/history
as the API endpoint, but this no longer seems to work. Now we call:
money/wallet/history
So if calls that used to work for you are now failing, take a look at that too. But I can tell you for sure that having your nonce as the last param in your QS for your signature is critical or your API calls will no longer work.
I also recommend re-creating a new API key in MtGox -we had to do so in order for our code to work properly as well. I have a hunch that this is because MtGox's recent API changes have invalidated old keys (likely to keep trading bots at bay while they figure out how to handle them without having the bots kill their API)

StreamSend API Blast, Sending Email

I need to use StreamSend API to send email, here is
StreamSend API Reference
I am making web request as post to following URL with proper credentials
https://app.streamsend.com/audiences/2/blasts.xml
StringBuilder sb = new StringBuilder();
sb.Append("https://app.streamsend.com/audiences/2/blasts.xml");
Uri uri = new Uri(sb.ToString());
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.ContentType = "application/xml";
StringBuilder strMail= new StringBuilder();
strMail.Append("<blast> ALL from api..... </blast>");
byte[] data = Encoding.ASCII.GetBytes(strMail.ToString());
Stream input = request.GetRequestStream();
input.Write(data, 0, data.Length);
input.Close();
HttpWebResponse nsResponse = (HttpWebResponse)request.GetResponse();
i am having err# 422 or 500. i would appreciate any help.
A couple of things. First, it looks like you're trying to do a POST request (you're sending data in the request stream). If you really want a POST request, you have to set request.Method = "POST";
Also, if you want an XML response, you need to set the Accept header. According to the documentation you listed, you need: request.Accept = "application/xml";
And you need to add your login id to the request, as well. I'm not sure how that's done. Perhaps in the request.Credentials property like this:
request.Credentials = new NetworkCredential("login_id", "your_key_here");
Finally, there's no reason to use StringBuilder if all you're doing is assigning strings. You can write, for example:
string urlString = "https://app.streamsend.com/audiences/2/blasts.xml"
Uri uri = new Uri(urlString);
or
byte[] data = Encoding.ASCII.GetBytes("<blast> ALL from api..... </blast>");

getting this error: "The remote server returned an error: (422) Unprocessable Entity." when doing post from C# to RoR

This code is for an outlook plugin. We're trying to POST to a page and are getting this error:
The remote server returned an error: (422) Unprocessable Entity.
The C# code is here:
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
Byte[] postData = asciiEncoding.GetBytes("email=e2#email.com&password=hunter2");
char[] resultHTML = asciiEncoding.GetChars(webClient.UploadData("http://url", "POST", postData));
string convertedResultHTML = new string(resultHTML);
Any idea what could be causing this?
POST data must be encoded prior to be sent out on the wire as ASCII, if you are sending character not in the ASCII range. You should try something like:
Byte[] postData = asciiEncoding.GetBytes(HttpUtility.UrlEncode("email=e2#email.com&password=hunter2"));
Because of its limited functionality, I avoid using WebClient and use WebRequest instead. The code below:
does not expect an HTTP 100 status code to be returned,
creates a CookieContainer to store any cookies we pick up,
sets the Content Length header, and
UrlEncodes each value in the post data.
Give the following a try and see if it works for you.
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.CookieContainer cookies = new System.Net.CookieContainer();
// this first request just ensures we have a session cookie, if one exists
System.Net.WebRequest req = System.Net.WebRequest.Create("http://localhost/test.aspx");
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
req.GetResponse().Close();
// this request submits the data to the server
req = System.Net.WebRequest.Create("http://localhost/test.aspx");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
string parms = string.Format("email={0}&password={1}",
System.Web.HttpUtility.UrlEncode("e2#email.com"),
System.Web.HttpUtility.UrlEncode("hunter2"));
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parms);
req.ContentLength = bytes.Length;
// perform the POST
using (System.IO.Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
// read the response
string response;
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return;
using (System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()))
{
response = sr.ReadToEnd().Trim();
}
}
// the variable response holds the results of the request...
Credits: Hanselman, Simon (SO Question)
This is the RoR application telling you that you have not formed a request that it can handle; the destination script exists (otherwise you'd see a 404), the request is being handled (otherwise you'd get a 400 error) and it's been encoded correctly (or you'd get a 415 error) but the actual instruction can't be carried out.
Looking at it, you seem to be loading some email information. The RoR application could be telling you that the username and password is wrong, or that the user doesn't exist, or something else. It's up to the RoR application itself.
I think the code itself is good; it's just that the app at the other end isn't happy about doing what you ask it. Are you missing something else in the request information, like a command? (eg command=getnetemails&email=e2#email.com&password=hunter2) Are you sure the email/password combination you are passing is good?
see here for more on the 422 error.
Add the below line above your code.
System.Net.ServicePointManager.Expect100Continue = false;
Are you trying to access an authentication required page?
it was solved by returning xml instead of just unstructured text on the RoR side

WebRequest to connect to the Wikipedia API

This may be a pathetically simple problem, but I cannot seem to format the post webrequest/response to get data from the Wikipedia API. I have posted my code below if anyone can help me see my problem.
string pgTitle = txtPageTitle.Text;
Uri address = new Uri("http://en.wikipedia.org/w/api.php");
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string action = "query";
string query = pgTitle;
StringBuilder data = new StringBuilder();
data.Append("action=" + HttpUtility.UrlEncode(action));
data.Append("&query=" + HttpUtility.UrlEncode(query));
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
request.ContentLength = byteData.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream.
StreamReader reader = new StreamReader(response.GetResponseStream());
divWikiData.InnerText = reader.ReadToEnd();
}
You might want to try a GET request first because it's a little simpler (you will only need to POST for wikipedia login). For example, try to simulate this request:
http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page
Here's the code:
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create("http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page");
using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
{
string ResponseText;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
ResponseText = reader.ReadToEnd();
}
}
Edit: The other problem he was experiencing on the POST request was, The exception is : The remote server returned an error: (417) Expectation failed. It can be solved by setting:
System.Net.ServicePointManager.Expect100Continue = false;
(This is from: HTTP POST Returns Error: 417 "Expectation Failed.")
I'm currently in the final stages of implementing an C# MediaWiki API which allows the easy scripting of most MediaWiki viewing and editing actions.
The main API is here: http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/O2_XRules_Database/_Rules/APIs/OwaspAPI.cs and here is an example of the API in use:
var wiki = new O2MediaWikiAPI("http://www.o2platform.com/api.php");
wiki.login(userName, password);
var page = "Test"; // "Main_Page";
wiki.editPage(page,"Test content2");
var rawWikiText = wiki.raw(page);
var htmlText = wiki.html(page);
return rawWikiText.line().line() + htmlText;
You seem to be pushing the input data on HTTP POST, but it seems you should use HTTP GET.
From the MediaWiki API docs:
The API takes its input through
parameters in the query string. Every
module (and every action=query
submodule) has its own set of
parameters, which is listed in the
documentation and in action=help, and
can be retrieved through
action=paraminfo.
http://www.mediawiki.org/wiki/API:Data_formats

Categories