4

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

enter image description here

Mike
  • 2,862
  • 10
  • 42
  • 55
  • I would suggest looking at examples on how splitting a download into multiple sections and downloading each piece individually works. Here is a SO about combining split chunks with PHP http://stackoverflow.com/questions/9011138/handling-pluploads-chunked-uploads-on-the-server-side All you have to do is figure out how to split the file in chunks from .NET and you should be golden – user3036342 May 08 '14 at 10:13

2 Answers2

2

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

Community
  • 1
  • 1
nl-x
  • 11,762
  • 7
  • 33
  • 61
0

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.

Seti
  • 2,169
  • 16
  • 26
  • 1
    I had already figured out how to do this but as I said above I would like the ability to send pieces of the file at a time which I don't think is possible with UploadFile. Perhaps the best solution would be to split my file into multiple files of the size I want to send and then use UploadFile on each one? That seems like it wouldn't be very inefficient compared to just reading pieces into memory and sending it. – Mike May 08 '14 at 10:06