I want to upload files from a Windows C# application to a web server running PHP.
I am aware of the WebClient.UploadFile method but I would like to be able to upload a file in chunks so that I can monitor progress and be able to pause/resume.
Therefore I am reading part of the file and using the WebClient.UploadData method.
The problem I am having is that I don't know how to access data sent with UploadData from php. If I do print_r on the post data I can see that there is binary data but I don't know the key to access it. How can I access the binary data? Is there a better way I should be doing this altogether?
String file = "C:\\Users\\Public\\uploadtest\\4.wmv";
using (BinaryReader b = new BinaryReader(File.Open(file, FileMode.Open)))
{
int pos = 0;
int required = 102400;
b.BaseStream.Seek(pos, SeekOrigin.Begin);
byte[] by = b.ReadBytes(required);
using (WebClient wc = new WebClient()){
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
byte[] result = wc.UploadData("http://192.168.0.52/html/application.php", "POST", by);
String s = System.Text.Encoding.UTF8.GetString(result, 0, result.Length);
MessageBox.Show(s);
}
}
This is how I do my HTTP communications.
I guess when I reach using(), the HTTP connection is being set up, and inside the using() {...} body you can do pausing and stuff.
string valueString = "...";
string uriString = "http://someUrl/somePath";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uriString);
httpWebRequest.Method = "POST";
string postData = "key=" + Uri.EscapeDataString(valueString);
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.ContentLength = byteArray.Length;
using (Stream dataStream = httpWebRequest.GetRequestStream())
{
// do pausing and stuff here by using a while loop and changing byteArray.Length into the desired length of your chunks
dataStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
Stream receiveStream = httpWebResponse.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream);
string internalResponseString = readStream.ReadToEnd();
But when uploading a file, you should probably use multipart/form-data in stead of application/x-www-form-urlencoded. See also: http://www.php.net/manual/en/features.file-upload.post-method.php
In php you can use the superglobal variable $_FILES (eg print_r($_FILES); ) to access the uploaded file.
And also read this: https://stackoverflow.com/a/20000831/1209443 for more information how to deal with multipart/form-data
Use this. This will work for sure.
System.Net.WebClient Client = new System.Net.WebClient();
Client.Headers.Add("Content-Type", "binary/octet-stream");
byte[] result = Client.UploadFile("http://192.168.0.52/mipzy/html/application.php", "POST", file);
string s = System.Text.Encoding.UTF8.GetString(result, 0, result.Length);
MessageBox.Show(s);
Or the one with using
using (System.Net.WebClient Client = new System.Net.WebClient())
{
Client.Headers.Add("Content-Type", "binary/octet-stream");
byte[] result = Client.UploadFile("http://192.168.0.52/mipzy/html/application.php", "POST", file);
string s = System.Text.Encoding.UTF8.GetString(result, 0, result.Length);
MessageBox.Show(s);
}
Without binary reader. IF you want binary reader, you also must provide some multipart parameters to the form. This is automatically done by that UploadFile thing.
Related
I'm sending the content of the file via post request using WebRequest.
It is working fine when the file has less content but it is not sending any data when the content is large.
WebRequest HttpWebRequest = WebRequest.Create("http://testapi.com");
HttpWebRequest.Method = "POST";
HttpWebRequest.Headers.Add("X-API-KEY", APIKEY);
byte[] data = Encoding.UTF8.GetBytes(postdata);
HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
HttpWebRequest.ContentLength = data.Length;
Stream requestStream = HttpWebRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
I'm getting the empty array at the API end. It should get all the file content that I'm sending.
I tried with postman and it worked fine. So I think the issue is in c# side.
You have a big file, first of all you have to encode it:
StringBuilder fileContents = new StringBuilder();
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader(#"c:\test.txt");
while((line = file.ReadLine()) != null)
{
fileContents.Append( WebUtility.UrlEncod(line)+ '%0A');
}
file.Close();
after that
Uri uri = new Uri("http://testapi.com");
using(WebClient myWebClient = new WebClient())
{
myWebClient.Headers.Add("X-API-KEY",APIKEY);
myWebClient.Headers.Add("Content-Type","application/x-www-form- urlencoded");
string result = myWebClient.UploadString(uri ,"plu_str="+fileContents.ToString());
}
I have the following problem.
I have the method that sends json via POST:
public string request (string handler, string data)
{
WebRequest request = WebRequest.Create(baseUri + "/?h=" + handler);
request.Method = "POST";
request.ContentType = "text/json";
string json = "json=" + data;
byte[] bytes = Encoding.ASCII.GetBytes(json);
request.ContentLength = bytes.Length;
Stream str = request.GetRequestStream();
str.Write(bytes, 0, bytes.Length);
str.Close();
WebResponse res = request.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
lastResponse = sr.ReadToEnd();
return lastResponse;
}
When using the method on the server does not come data in POST. As if this code is not executed.
Stream str = request.GetRequestStream();
str.Write(bytes, 0, bytes.Length);
str.Close();
On the server i'm using following php script for debug:
<?php print_r($_POST); ?>
Also tried to write to the stream as follows:
StreamWriter strw = new StreamWriter(request.GetRequestStream());
strw.Write(json);
strw.Close();
The result - a zero response. In response comes an empty array.
The Problem is, that PHP does not "recognize" the text/json-content type. And thus does not parse the POST-request-data. You have to use the application/x-www-form-urlencoded content-type and secondly you have to encode the POST-data properly:
// ...
request.ContentType = "application/x-www-form-urlencoded";
string json = "json=" + HttpUtility.UrlEncode(data);
// ...
If you intend to supply the JSON-data directly you can leave the content-type to text/json and pass the data directly as json (without the "json=" part):
string json = data;
But in that case you have to change your script on the PHP-side to directly read the post data:
// on your PHP side:
$post_body = file_get_contents('php://input');
$json = json_decode($post_body);
Have you thought about using WebClient.UploadValues. Using the NameValueCollection with "json" as the name and JSON data string as the value?
This seems like the easiest way to go. Don't forget you can always add headers and credentials to the WebClient.
I have this php code in server :
foreach($_POST as $pdata)
echo " *-* ". $pdata." *-*<br> ";
and i am sending post data by httpwebrequest in c# :
HttpWebRequest httpWebRequest = HttpWebRequest.Create("http://127.0.0.1/22") as HttpWebRequest;
//Specifing the Method
httpWebRequest.Method = "POST";
//Data to Post to the Page, itis key value pairs; separated by "&"
string data = "Username=username&password=password";
//Setting the content type, it is required, otherwise it will not work.
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
//Getting the request stream and writing the post data
using (StreamWriter sw = new StreamWriter(httpWebRequest.GetRequestStream()))
{
sw.Write(data);
}
//Getting the Respose and reading the result.
HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
{
MessageBox.Show(sr.ReadToEnd());
}
static html codes of php page are shown.
but nothing of posted value are shown in messagebox .that means no data are posted.
what is wrong?
You need to get the bytes of the data.
Try this code, from this guy's blog post.
public string Post(string url, string data) {
string vystup = null;
try
{
//Our postvars
byte[] buffer = Encoding.ASCII.GetBytes(data);
//Initialisation, we use localhost, change if appliable
HttpWebRequest WebReq = (HttpWebRequest)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!
HttpWebResponse WebResp = (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)
{
MessageBox.Show(ex.Message);
}
return vystup.Trim()+"\n";
}
What I'm trying to do is have my PHP page display a string that I've created through a function in my C# application, via System.Net.WebClient.
That's really it. In it' s simplest form, I have:
WebClient client = new WebClient();
string URL = "http://wwww.blah.com/page.php";
string TestData = "wooooo! test!!";
byte[] SendData = client.UploadString(URL, "POST", TestData);
So, I'm not even sure if that's the right way to do it.. and I'm not sure how to actually OBTAIN that string and display it on the PHP page. something like print_r(SendData) ??
ANY help would be greatly appreciated!
There are two halves to posting. 1) The code that posts to a page and 2) the page that receives it.
For 1)
Your C# looks ok. I personally would use:
string url = "http://wwww.blah.com/page.php";
string data = "wooooo! test!!";
using(WebClient client = new WebClient()) {
client.UploadString(url, data);
}
For 2)
In your PHP page:
if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
{
$postData = file_get_contents('php://input');
print $postData;
}
Read about reading post data in PHP here:
http://us.php.net/manual/en/wrappers.php.php
http://php.net/manual/en/reserved.variables.httprawpostdata.php
Use This Codes To Send String From C# With Post Method
try
{
string url = "";
string str = "test";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
string Data = "message="+str;
byte[] postBytes = Encoding.ASCII.GetBytes(Data);
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postBytes.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream resStream = response.GetResponseStream();
var sr = new StreamReader(response.GetResponseStream());
string responseText = sr.ReadToEnd();
}
catch (WebException)
{
MessageBox.Show("Please Check Your Internet Connection");
}
and php page
<?php
if (isset($_POST['message']))
{
$msg = $_POST['message'];
echo $msg;
}
?>
I'm trying to send a file in chunks to an HttpHandler but when I receive the request in the HttpContext, the inputStream is empty.
So a: while sending I'm not sure if my HttpWebRequest is valid
and b: while receiving I'm not sure how to retrieve the stream in the HttpContext
Any help greatly appreciated!
This how I make my request from client code:
private void Post(byte[] bytes)
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost:2977/Upload");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.SendChunked = true;
req.Timeout = 400000;
req.ContentLength = bytes.Length;
req.KeepAlive = true;
using (Stream s = req.GetRequestStream())
{
s.Write(bytes, 0, bytes.Length);
s.Close();
}
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
}
this is how I handle the request in the HttpHandler:
public void ProcessRequest(HttpContext context)
{
Stream chunk = context.Request.InputStream; //it's empty!
FileStream output = new FileStream("C:\\Temp\\myTempFile.tmp", FileMode.Append);
//simple method to append each chunk to the temp file
CopyStream(chunk, output);
}
I suspect it might be confusing that you are uploading it as form-encoded. but that isn't what you are sending (unless you're glossing over something). Is that MIME type really correct?
How big is the data? Do you need chunked upload? Some servers might not like this in a single request; I'd be tempted to use multiple simple requests via WebClient.UploadData.
i was trying the same idea and was successfull in sending file through Post httpwebrequest. Please see the following code sample
private void ChunkRequest(string fileName,byte[] buffer)
{
//Request url, Method=post Length and data.
string requestURL = "http://localhost:63654/hello.ashx";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Chunk(buffer) is converted to Base64 string that will be convert to Bytes on the handler.
string requestParameters = #"fileName=" + fileName +
"&data=" + HttpUtility.UrlEncode( Convert.ToBase64String(buffer) );
// finally whole request will be converted to bytes that will be transferred to HttpHandler
byte[] byteData = Encoding.UTF8.GetBytes(requestParameters);
request.ContentLength = byteData.Length;
Stream writer = request.GetRequestStream();
writer.Write(byteData, 0, byteData.Length);
writer.Close();
// here we will receive the response from HttpHandler
StreamReader stIn = new StreamReader(request.GetResponse().GetResponseStream());
string strResponse = stIn.ReadToEnd();
stIn.Close();
}
I have blogged about it, you see the whole HttpHandler/HttpWebRequest post here
http://aspilham.blogspot.com/2011/03/file-uploading-in-chunks-using.html
I hope this will help