Having stumbled upon a problem when doing this, I first searched SO to try and find if others were having similar problems, and found this question: POST data to a PHP page from C# WinForm
However, when I tried the code example given in the answer to this question, it does not work. The PHP script that I am making a request to responds with a message indicating that the POST variable that has to be set is not set. Here's my C# code:
HttpWebRequest POSTreq =
(HttpWebRequest)WebRequest.Create("http://82.41.255.140/api/post-ptr");
string POSTdata = "action=" + HttpUtility.UrlEncode("date");
byte[] data = Encoding.ASCII.GetBytes(POSTdata);
POSTreq.Method = "POST";
POSTreq.ContentType = "application/x-www-form-urlencoded";
POSTreq.ContentLength = data.LongLength;
POSTreq.GetRequestStream().Write(data, 0, data.Length);
HttpWebResponse POSTres = (HttpWebResponse)POSTreq.GetResponse();
Console.WriteLine("HTTP Status Code {0}", POSTres.StatusCode);
Console.WriteLine("Response Method: {0}", POSTres.Method);
Console.WriteLine("Response Text: {0}",
new StreamReader(POSTres.GetResponseStream()).ReadToEnd());
Console.ReadLine();
And this is the code inside the PHP script:
<?php
$A = strtolower($_POST["action"]);
if ($A == "date")
{
echo date("c");
}
else if ($A == "ip")
{
echo $_SERVER["REMOTE_ADDR"];
}
else if ($A == null || $A == "")
{
echo "bad_request:no_argument:POST_action";
}
else
{
echo "bad_request:invalid_argument:POST_action";
}
exit();
?>
When I make the POST request from my C# program, I see the following screen, indicating that the variable action has not been set. Am I missing the obvious in my code?
Thanks to those who reply.
You might need to flush the stream. I usually do it like this:
string POSTdata = "action=" + HttpUtility.UrlEncode("date");
byte[] data = Encoding.ASCII.GetBytes(POSTdata);
POSTreq.Method = "POST";
POSTreq.ContentType = "application/x-www-form-urlencoded";
POSTreq.ContentLength = data.LongLength;
using (Stream stream = POSTreq.GetRequestStream()) {
stream.Write(data, 0, data.Length);
stream.Flush();
}
You're not closing the request stream. See this example in the MSDN docs, which is very close to your code.
EDIT
Your PHP null check is incorrect also. See this article.
I've found the problem.
It turns out I'd left off the trailing / in the request, and the request was getting 301'd, which for whatever reason removed the post variables.
So http://82.41.255.140/api/post-ptr should have been http://82.41.255.140/api/post-ptr/.
Thanks to everyone who answered, I've +1'd you all.
Related
My aim is to get content from a website (for instance a league table from a sports website) and put it in a .txt file so that I can code with a local file.
I have tried multiple lines of code and others examples such as:
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("http://www.stackoverflow.com");
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("http://www.stackoverflow.com");
// execute the request
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
// fill the buffer with data
count = resStream.Read(buf, 0, buf.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buf, 0, count);
// continue building the string
sb.Append(tempString);
}
while (count > 0); // any more data to read?
}
My issue is when trying this, is that the words request and response are underlined in read and all the tokens are invalid.
Is there a better method to get content from a website to a .txt file or is there a way to fix the code supplied?
Thanks
is there a way to fix the code supplied?
The code you submitted works for me, make sure you have the proper name spaces defined.
In this case : using System.Net;
Or might it be that the duplicate creation of the variable request isn't a typo?
If so remove one of the request variables.
Is there a better method to get content from a website to a .txt file
Since you're reading all the content from the site anyway there isn't really a need for the while loop. Instead you can use the ReadToEnd method supplied by the StreamReader.
string siteContent = "";
using (StreamReader reader = new StreamReader(resStream)) {
siteContent = reader.ReadToEnd();
}
Also be sure to dispose of the WebResponse, other than that your code should work fine.
I'm using C# to get data from endless http-stream. I used TCP Client before, but now I want to add status code exceptions, it's much easier to do it with HttpWebResponse. I got response, but problem is I can't read chunks coming from server. Everything looks fine, but I must be missed something. Debug shows execution is stucked at ReadLine(). Also I can see there's some data in stream buffer.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://" + url + "/stream/" + from + "?token=" + token);
using(HttpWebResponse res = (HttpWebResponse)req.GetResponse())
using(StreamReader streadReader = new StreamReader(res.GetResponseStream(),Encoding.UTF8)){
//Start parsing cycle
while(!streadReader.EndOfStream && !worker.CancellationPending) {
string resultLine = streadReader.ReadLine();
System.Diagnostics.Trace.WriteLine(resultLine);
if(!resultLine.StartsWith("{")) continue;
newQuote quote = JsonConvert.DeserializeObject<newQuote>(resultLine);
worker.ReportProgress(0, quote);
}
}
I'v found the error. I was using ReadLine(), but never sent "\r\n" from server side. I patched my server to send \r\n after JSON object ant it works fine now.
Another option is to use Read() method. It's not waiting for the end of line, but you must know chunk length.
Thanks for the help :)
Upd: How to parse string using Read() method:
while(!streamReader.EndOfStream && !worker.CancellationPending) {
char[] buffer = new char[1024];
streamReader.Read(buffer, 0, buffer.Length);
string resultLine="";
for(int i = 0; i < buffer.Length; i++) {
if(buffer[i] != 0) resultLine += buffer[i].ToString();
}
newQuote quote = JsonConvert.DeserializeObject<newQuote>(resultLine);
worker.ReportProgress(0, quote);
}
I want to send a string (data) from C# to PHP but I am unable to receive data in PHP . Here is my C# code
string deviceUrl ="http://localhost/CBIRS/clusteringdata.php";
HttpWebRequest reqDevice = (HttpWebRequest)WebRequest.Create(deviceUrl);
reqDevice.Method = "POST";
string deviceData = "status="+ data;
byte[] postDeviceBytes = Encoding.ASCII.GetBytes(deviceData);
reqDevice.ContentType = "application/x-www-form-urlencoded";
reqDevice.ContentLength = postDeviceBytes.Length;
Stream requestDeviceStream = reqDevice.GetRequestStream();
requestDeviceStream.Write(postDeviceBytes, 0, postDeviceBytes.Length);
requestDeviceStream.Close();
and my PHP code is as follows.
if(isset($_POST['status']))
{
$tempdata=explode('$',$_POST['status']);
var_dump($tempdata);
}
else
{
echo "Data not recieved";
}
after running C# application when I run PHP file it always goes to else part. How can I correct it?
You aren't encoding the POST data. When you send POST data, the values must be URL encoded. I suspect there is a special character in data that is causing PHP to fail to parse the POST data.
To encode the value:
string deviceData = "status="+ HttpUtility.UrlEncode(data);
Note that the $tempdata variable is never used in your PHP.
Have you tried to display the response of your request in your C# program ? Add another echo "hello"; out of your condition to see if the connection works.
the page at https://qrng.physik.hu-berlin.de/ provides a high bit rate quantum number generator web service and I'm trying to access that service.
However I could not manage to do so. This is my current code:
using System;
using System.Collections.Generic;
using System.Linq;
using S=System.Text;
using System.Security.Cryptography;
using System.IO;
namespace CS_Console_App
{
class Program
{
static void Main()
{
System.Net.ServicePointManager.Expect100Continue = false;
var username = "testuser";
var password = "testpass";
System.Diagnostics.Debug.WriteLine(Post("https://qrng.physik.hu-berlin.de/", "username="+username+"&password="+password));
Get("http://qrng.physik.hu-berlin.de/download/sampledata-1MB.bin");
}
public static void Get(string url)
{
var my_request = System.Net.WebRequest.Create(url);
my_request.Credentials = System.Net.CredentialCache.DefaultCredentials;
var my_response = my_request.GetResponse();
var my_response_stream = my_response.GetResponseStream();
var stream_reader = new System.IO.StreamReader(my_response_stream);
var content = stream_reader.ReadToEnd();
System.Diagnostics.Debug.WriteLine(content);
stream_reader.Close();
my_response_stream.Close();
}
public static string Post(string url, string data)
{
string vystup = null;
try
{
//Our postvars
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(data);
//Initialisation, we use localhost, change if appliable
System.Net.HttpWebRequest WebReq = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
//Our method is post, otherwise the buffer (postvars) would be useless
WebReq.Method = "POST";
//We use form contentType, for the postvars.
WebReq.ContentType = "application/x-www-form-urlencoded";
//The length of the buffer (postvars) is used as contentlength.
WebReq.ContentLength = buffer.Length;
//We open a stream for writing the postvars
Stream PostData = WebReq.GetRequestStream();
//Now we write, and afterwards, we close. Closing is always important!
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
//Get the response handle, we have no true response yet!
System.Net.HttpWebResponse WebResp = (System.Net.HttpWebResponse)WebReq.GetResponse();
//Let's show some information about the response
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.Server);
//Now, we read the response (the string), and output it.
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
vystup = _Answer.ReadToEnd();
//Congratulations, you just requested your first POST page, you
//can now start logging into most login forms, with your application
//Or other examples.
}
catch (Exception ex)
{
throw ex;
}
return vystup.Trim() + "\n";
}
}
}
I'm having 403 forbidden error when I try to do a get request on http://qrng.physik.hu-berlin.de/download/sampledata-1MB.bin.
After debugging abit, I've realised that even though I've supplied a valid username and password, the response html that was sent after my POST request indicate that I was actually not logon to the system after my POST request.
Does anyone know why is this the case, and how may I work around it to call the service?
Bump. can anyone get this to work or is the site just a scam?
The site is surely not a scam. I developed the generator and I put my scientific reputation in it. The problem is that you are trying to use the service in a way that was not intended. The sample files were really only meant to be downloaded manually for basic test purposes. Automated access to fetch data into an application was meant to be implemented through the DLLs we provide.
On the other hand, I do not know of any explicit intent to prevent your implementation to work. I suppose if a web browser can log in and fetch data, some program should be able to do the same. Maybe only the login request is just a little more complicated. No idea. The server software was developed by someone else and I cannot bother him with this right now.
Mick
Actually, the generator can now also be purchased. See here:
http://www.picoquant.com/products/pqrng150/pqrng150.htm
Have you tried to change this
my_request.Credentials = System.Net.CredentialCache.DefaultCredentials
to
my_request.Credentials = new NetworkCredential(UserName,Password);
as described on MSDN page?
In my application I use the WebClient class to download files from a Webserver by simply calling the DownloadFile method. Now I need to check whether a certain file exists prior to downloading it (or in case I just want to make sure that it exists). I've got two questions with that:
What is the best way to check whether a file exists on a server without transfering to much data across the wire? (It's quite a huge number of files I need to check)
Is there a way to get the size of a given remote file without downloading it?
Thanks in advance!
WebClient is fairly limited; if you switch to using WebRequest, then you gain the ability to send an HTTP HEAD request. When you issue the request, you should either get an error (if the file is missing), or a WebResponse with a valid ContentLength property.
Edit: Example code:
WebRequest request = WebRequest.Create(new Uri("http://www.example.com/"));
request.Method = "HEAD";
using(WebResponse response = request.GetResponse()) {
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}
When you request file using the WebClient Class, the 404 Error (File Not Found) will lead to an exception. Best way is to handle that exception and use a flag which can be set to see if the file exists or not.
The example code goes as follows:
System.Net.HttpWebRequest request = null;
System.Net.HttpWebResponse response = null;
request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("www.example.com/somepath");
request.Timeout = 30000;
try
{
response = (System.Net.HttpWebResponse)request.GetResponse();
flag = 1;
}
catch
{
flag = -1;
}
if (flag==1)
{
Console.WriteLine("File Found!!!");
}
else
{
Console.WriteLine("File Not Found!!!");
}
You can put your code in respective if blocks.
Hope it helps!
What is the best way to check whether a file exists on a server
without transfering to much data across the wire?
You can test with WebClient.OpenRead to open the file stream without reading all the file bytes:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
// ^ throws System.Net.WebException: 'Could not find file...' if file is not present
stream.Close();
}
This will indicate if the file exists at the remote location or not.
To fully read the file stream, you would do:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
StreamReader sr = new StreamReader(stream);
Console.WriteLine(sr.ReadToEnd());
stream.Close();
}
In case anyone stuck with ssl certificate issue
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback
(
delegate { return true; }
);
WebRequest request = WebRequest.Create(new Uri("http://.com/flower.zip"));
request.Method = "HEAD";
using (WebResponse response = request.GetResponse())
{
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}