[c#] How to upload file to server with HTTP POST multipart/form-data?

I am developing Windows Phone 8 app. I want to upload SQLite database via PHP web service using HTTP POST request with MIME type multipart/form-data & a string data called "userid=SOME_ID".

I don't want to use 3rd party libs like HttpClient, RestSharp or MyToolkit. I tried the below code but it doesn't upload the file & also doesn't give me any errors. It's working fine in Android, PHP, etc so there's no issue in web service. Below is my given code (for WP8). what's wrong with it?

I've googled and I'm not getting specific for WP8

async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(DBNAME);
    //Below line gives me file with 0 bytes, why? Should I use 
    //IsolatedStorageFile instead of StorageFile
    //var file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBNAME);
    byte[] fileBytes = null;
    using (var stream = await file.OpenReadAsync())
    {
        fileBytes = new byte[stream.Size];
        using (var reader = new DataReader(stream))
        {
            await reader.LoadAsync((uint)stream.Size);
            reader.ReadBytes(fileBytes);
        }
    }

    //var res = await HttpPost(Util.UPLOAD_BACKUP, fileBytes);
    HttpPost(fileBytes);
}

private void HttpPost(byte[] file_bytes)
{
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.myserver.com/upload.php");
    httpWebRequest.ContentType = "multipart/form-data";
    httpWebRequest.Method = "POST";
    var asyncResult = httpWebRequest.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, file_bytes); }, httpWebRequest);  
}

private void GetRequestStreamCallback(IAsyncResult asynchronousResult, byte[] postData)  
{
    //DON'T KNOW HOW TO PASS "userid=some_user_id"  
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;  
    Stream postStream = request.EndGetRequestStream(asynchronousResult);  
    postStream.Write(postData, 0, postData.Length);  
    postStream.Close();  
    var asyncResult = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);  
}  

private void GetResponseCallback(IAsyncResult asynchronousResult)  
{  
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;  
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);  
    Stream streamResponse = response.GetResponseStream();  
    StreamReader streamRead = new StreamReader(streamResponse);  
    string responseString = streamRead.ReadToEnd();  
    streamResponse.Close();  
    streamRead.Close();  
    response.Close();  
}  

I also tried to solve my problem in Windows 8 but it's also not working.

public async Task Upload(byte[] fileBytes)
{
    using (var client = new HttpClient())
    {
        using (var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture)))
        {
            content.Add(new StreamContent(new MemoryStream(fileBytes)));
            //Not sure below line is true or not
            content.Add(new StringContent("userid=farhanW8"));
            using (var message = await client.PostAsync("http://www.myserver.com/upload.php", content))
            {
                var input = await message.Content.ReadAsStringAsync();
            }
        }
    }
}

This question is related to c# php post windows-phone-8 multipartform-data

The answer is


Here's my final working code. My web service needed one file (POST parameter name was "file") & a string value (POST parameter name was "userid").

/// <summary>
/// Occurs when upload backup application bar button is clicked. Author : Farhan Ghumra
 /// </summary>
private async void btnUploadBackup_Click(object sender, EventArgs e)
{
    var dbFile = await ApplicationData.Current.LocalFolder.GetFileAsync(Util.DBNAME);
    var fileBytes = await GetBytesAsync(dbFile);
    var Params = new Dictionary<string, string> { { "userid", "9" } };
    UploadFilesToServer(new Uri(Util.UPLOAD_BACKUP), Params, Path.GetFileName(dbFile.Path), "application/octet-stream", fileBytes);
}

/// <summary>
/// Creates HTTP POST request & uploads database to server. Author : Farhan Ghumra
/// </summary>
private void UploadFilesToServer(Uri uri, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
    string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
    httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
    httpWebRequest.Method = "POST";
    httpWebRequest.BeginGetRequestStream((result) =>
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            using (Stream requestStream = request.EndGetRequestStream(result))
            {
                WriteMultipartForm(requestStream, boundary, data, fileName, fileContentType, fileData);
            }
            request.BeginGetResponse(a =>
            {
                try
                {
                    var response = request.EndGetResponse(a);
                    var responseStream = response.GetResponseStream();
                    using (var sr = new StreamReader(responseStream))
                    {
                        using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
                        {
                            string responseString = streamReader.ReadToEnd();
                            //responseString is depend upon your web service.
                            if (responseString == "Success")
                            {
                                MessageBox.Show("Backup stored successfully on server.");
                            }
                            else
                            {
                                MessageBox.Show("Error occurred while uploading backup on server.");
                            } 
                        }
                    }
                }
                catch (Exception)
                {

                }
            }, null);
        }
        catch (Exception)
        {

        }
    }, httpWebRequest);
}

/// <summary>
/// Writes multi part HTTP POST request. Author : Farhan Ghumra
/// </summary>
private void WriteMultipartForm(Stream s, string boundary, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
    /// The first boundary
    byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
    /// the last boundary.
    byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
    /// the form data, properly formatted
    string formdataTemplate = "Content-Dis-data; name=\"{0}\"\r\n\r\n{1}";
    /// the form-data file upload, properly formatted
    string fileheaderTemplate = "Content-Dis-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";

    /// Added to track if we need a CRLF or not.
    bool bNeedsCRLF = false;

    if (data != null)
    {
        foreach (string key in data.Keys)
        {
            /// if we need to drop a CRLF, do that.
            if (bNeedsCRLF)
                WriteToStream(s, "\r\n");

            /// Write the boundary.
            WriteToStream(s, boundarybytes);

            /// Write the key.
            WriteToStream(s, string.Format(formdataTemplate, key, data[key]));
            bNeedsCRLF = true;
        }
    }

    /// If we don't have keys, we don't need a crlf.
    if (bNeedsCRLF)
        WriteToStream(s, "\r\n");

    WriteToStream(s, boundarybytes);
    WriteToStream(s, string.Format(fileheaderTemplate, "file", fileName, fileContentType));
    /// Write the file data to the stream.
    WriteToStream(s, fileData);
    WriteToStream(s, trailer);
}

/// <summary>
/// Writes string to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, string txt)
{
    byte[] bytes = Encoding.UTF8.GetBytes(txt);
    s.Write(bytes, 0, bytes.Length);
}

/// <summary>
/// Writes byte array to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, byte[] bytes)
{
    s.Write(bytes, 0, bytes.Length);
}

/// <summary>
/// Returns byte array from StorageFile. Author : Farhan Ghumra
/// </summary>
private async Task<byte[]> GetBytesAsync(StorageFile file)
{
    byte[] fileBytes = null;
    using (var stream = await file.OpenReadAsync())
    {
        fileBytes = new byte[stream.Size];
        using (var reader = new DataReader(stream))
        {
            await reader.LoadAsync((uint)stream.Size);
            reader.ReadBytes(fileBytes);
        }
    }

    return fileBytes;
}

I am very much thankful to Darin Rousseau for helping me.


Here is what worked for me while sending the file as mult-form data:

    public T HttpPostMultiPartFileStream<T>(string requestURL, string filePath, string fileName)
    {
        string content = null;

        using (MultipartFormDataContent form = new MultipartFormDataContent())
        {
            StreamContent streamContent;
            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                streamContent = new StreamContent(fileStream);

                streamContent.Headers.Add("Content-Type", "application/octet-stream");
                streamContent.Headers.Add("Content-Disposition", string.Format("form-data; name=\"file\"; filename=\"{0}\"", fileName));
                form.Add(streamContent, "file", fileName);

                using (HttpClient client = GetAuthenticatedHttpClient())
                {
                    HttpResponseMessage response = client.PostAsync(requestURL, form).GetAwaiter().GetResult();
                    content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();



                    try
                    {
                        return JsonConvert.DeserializeObject<T>(content);
                    }
                    catch (Exception ex)
                    {
                        // Log the exception
                    }

                    return default(T);
                }
            }
        }
    }

GetAuthenticatedHttpClient used above can be:

private HttpClient GetAuthenticatedHttpClient()
{
    HttpClient httpClient = new HttpClient();
    httpClient.BaseAddress = new Uri(<yourBaseURL>));
    httpClient.DefaultRequestHeaders.Add("Token, <yourToken>);
    return httpClient;
}

This simplistic version also works.

public void UploadMultipart(byte[] file, string filename, string contentType, string url)
{
    var webClient = new WebClient();
    string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
    webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
    var fileData = webClient.Encoding.GetString(file);
    var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, filename, contentType, fileData);

    var nfile = webClient.Encoding.GetBytes(package);

    byte[] resp = webClient.UploadData(url, "POST", nfile);
}

Add any extra required headers if needed.


I know this is and old thread, but I was fighting with this and I would like to share my solution.

This solution works with HttpClient and MultipartFormDataContent, from System.Net.Http. You can release it with .NET Core 1.0 or higher, or .NET Framework 4.5 or higher.

As a quick summary, it's an asynchronous method that receives as parameters the URL in which you want to perform the POST, a key/value collection for sending strings, and a key/value collection for sending files.

private static async Task<HttpResponseMessage> Post(string url, NameValueCollection strings, NameValueCollection files)
{
    var formContent = new MultipartFormDataContent(/* If you need a boundary, you can define it here */);

    // Strings
    foreach (string key in strings.Keys)
    {
        string inputName = key;
        string content = strings[key];

        formContent.Add(new StringContent(content), inputName);
    }

    // Files
    foreach (string key in files.Keys)
    {
        string inputName = key;
        string fullPathToFile = files[key];

        FileStream fileStream = File.OpenRead(fullPathToFile);
        var streamContent = new StreamContent(fileStream);
        var fileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
        formContent.Add(fileContent, inputName, Path.GetFileName(fullPathToFile));
    }

    var myHttpClient = new HttpClient();
    var response = await myHttpClient.PostAsync(url, formContent);
    //string stringContent = await response.Content.ReadAsStringAsync(); // If you need to read the content

    return response;
}

You can prepare your POST like this (you can add so many strings and files as you need):

string url = @"http://yoursite.com/upload.php"

NameValueCollection strings = new NameValueCollection();
strings.Add("stringInputName1", "The content for input 1");
strings.Add("stringInputNameN", "The content for input N");

NameValueCollection files = new NameValueCollection();
files.Add("fileInputName1", @"FullPathToFile1"); // Path + filename
files.Add("fileInputNameN", @"FullPathToFileN");

And finally, call the method like this:

var result = Post(url, strings, files).GetAwaiter().GetResult();

If you want, you can check your status code, and show the reason as below:

if (result.StatusCode == HttpStatusCode.OK)
{
    // Logic if all was OK
}
else
{
    // You can show a message like this:
    Console.WriteLine(string.Format("Error. StatusCode: {0} | ReasonPhrase: {1}", result.StatusCode, result.ReasonPhrase));
}

And if someone need it, here I let a small example of how to receive store a file with PHP (at the other side of our .Net app):

<?php

if (isset($_FILES['fileInputName1']) && $_FILES['fileInputName1']['error'] === UPLOAD_ERR_OK)
{
  $fileTmpPath = $_FILES['fileInputName1']['tmp_name'];
  $fileName = $_FILES['fileInputName1']['name'];

  move_uploaded_file($fileTmpPath, '/the/final/path/you/want/' . $fileName);
}

I hope you find it useful, I am attentive to your questions.


Basic implementation using MultipartFormDataContent :-

HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();

form.Add(new StringContent(username), "username");
form.Add(new StringContent(useremail), "email");
form.Add(new StringContent(password), "password");            
form.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "profile_pic", "hello1.jpg");
HttpResponseMessage response = await httpClient.PostAsync("PostUrl", form);

response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;

Top to @loop answer.

We got below error for Asp.Net MVC, Unable to connect to the remote server

Fix: After adding the below code in Web.Confing issue has been resolved for us

  <system.net>
    <defaultProxy useDefaultCredentials="true" >
    </defaultProxy>
  </system.net>

The below code reads a file, converts it to a byte array and then makes a request to the server.

    public void PostImage()
    {
        HttpClient httpClient = new HttpClient();
        MultipartFormDataContent form = new MultipartFormDataContent();

        byte[] imagebytearraystring = ImageFileToByteArray(@"C:\Users\Downloads\icon.png");
        form.Add(new ByteArrayContent(imagebytearraystring, 0, imagebytearraystring.Count()), "profile_pic", "hello1.jpg");
        HttpResponseMessage response = httpClient.PostAsync("your url", form).Result;

        httpClient.Dispose();
        string sd = response.Content.ReadAsStringAsync().Result;
    }

    private byte[] ImageFileToByteArray(string fullFilePath)
    {
        FileStream fs = File.OpenRead(fullFilePath);
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
        fs.Close();
        return bytes;
    }

I was also wanted to upload stuff to a Server and it was a Spring application i finally discovered that I needed to acctually set an content type for it to interpret it as a file. Just like this:

...
MultipartFormDataContent form = new MultipartFormDataContent();
var fileStream = new FileStream(uniqueTempPathInProject, FileMode.Open);
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentType=new MediaTypeHeaderValue("application/zip");
form.Add(streamContent, "file",fileName);
...

It work for window phone 8.1. You can try this.

Dictionary<string, object> _headerContents = new Dictionary<string, object>();
const String _lineEnd = "\r\n";
const String _twoHyphens = "--";
const String _boundary = "*****";
private async void UploadFile_OnTap(object sender, System.Windows.Input.GestureEventArgs e)
{
   Uri serverUri = new Uri("http:www.myserver.com/Mp4UploadHandler", UriKind.Absolute);    
   string fileContentType = "multipart/form-data";       
   byte[] _boundarybytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _lineEnd);
   byte[] _trailerbytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _twoHyphens + _lineEnd);
   Dictionary<string, object> _headerContents = new Dictionary<string, object>();
   SetEndHeaders();  // to add some extra parameter if you need

   httpWebRequest = (HttpWebRequest)WebRequest.Create(serverUri);
   httpWebRequest.ContentType = fileContentType + "; boundary=" + _boundary;
   httpWebRequest.Method = "POST";
   httpWebRequest.AllowWriteStreamBuffering = false;  // get response after upload header part

   var fileName = Path.GetFileName(MediaStorageFile.Path);    
   Stream fStream = (await MediaStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)).AsStream(); //MediaStorageFile is a storage file from where you want to upload the file of your device    
   string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"" + _lineEnd + _lineEnd + "{1}" + _lineEnd;    
   long httpLength = 0;
   foreach (var headerContent in _headerContents) // get the length of upload strem
   httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes(string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value)).Length;

   httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes("Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd).Length
                                       + Encoding.UTF8.GetBytes(_lineEnd).Length * 2 + _trailerbytes.Length;
   httpWebRequest.ContentLength = httpLength + fStream.Length;  // wait until you upload your total stream 

    httpWebRequest.BeginGetRequestStream((result) =>
    {
       try
       {
         HttpWebRequest request = (HttpWebRequest)result.AsyncState;
         using (Stream stream = request.EndGetRequestStream(result))
         {
            foreach (var headerContent in _headerContents)
            {
               WriteToStream(stream, _boundarybytes);
               WriteToStream(stream, string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value));
             }

             WriteToStream(stream, _boundarybytes);
             WriteToStream(stream, "Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd);
             WriteToStream(stream, _lineEnd);

             int bytesRead = 0;
             byte[] buffer = new byte[2048];  //upload 2K each time

             while ((bytesRead = fStream.Read(buffer, 0, buffer.Length)) != 0)
             {
               stream.Write(buffer, 0, bytesRead);
               Array.Clear(buffer, 0, 2048); // Clear the array.
              }

              WriteToStream(stream, _lineEnd);
              WriteToStream(stream, _trailerbytes);
              fStream.Close();
         }
         request.BeginGetResponse(a =>
         { //get response here
            try
            {
               var response = request.EndGetResponse(a);
               using (Stream streamResponse = response.GetResponseStream())
               using (var memoryStream = new MemoryStream())
               {   
                   streamResponse.CopyTo(memoryStream);
                   responseBytes = memoryStream.ToArray();  // here I get byte response from server. you can change depends on server response
               }    
              if (responseBytes.Length > 0 && responseBytes[0] == 1)
                 MessageBox.Show("Uploading Completed");
              else
                  MessageBox.Show("Uploading failed, please try again.");
            }
            catch (Exception ex)
            {}
          }, null);
      }
      catch (Exception ex)
      {
         fStream.Close();                             
      }
   }, httpWebRequest);
}

private static void WriteToStream(Stream s, string txt)
{
   byte[] bytes = Encoding.UTF8.GetBytes(txt);
   s.Write(bytes, 0, bytes.Length);
 }

 private static void WriteToStream(Stream s, byte[] bytes)
 {
   s.Write(bytes, 0, bytes.Length);
 }

 private void SetEndHeaders()
 {
   _headerContents.Add("sId", LocalData.currentUser.SessionId);
   _headerContents.Add("uId", LocalData.currentUser.UserIdentity);
   _headerContents.Add("authServer", LocalData.currentUser.AuthServerIP);
   _headerContents.Add("comPort", LocalData.currentUser.ComPort);
 }

You can use this class:

using System.Collections.Specialized;
class Post_File
{
    public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc)
    {
        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
        byte[] boundarybytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");  // the first time it itereates, you need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick.  


        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
        wr.Method = "POST";
        wr.KeepAlive = true;
        wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
        wr.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        var nvc2 = new NameValueCollection();
        nvc2.Add("Accepts-Language", "en-us,en;q=0.5");
        wr.Headers.Add(nvc2);
        wr.ContentType = "multipart/form-data; boundary=" + boundary;


        Stream rs = wr.GetRequestStream();

        bool firstLoop = true;
        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
        foreach (string key in nvc.Keys)
        {
            if (firstLoop)
            {
                rs.Write(boundarybytesF, 0, boundarybytesF.Length);
                firstLoop = false;
            }
            else
            {
                rs.Write(boundarybytes, 0, boundarybytes.Length);
            }
            string formitem = string.Format(formdataTemplate, key, nvc[key]);
            byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
            rs.Write(formitembytes, 0, formitembytes.Length);
        }
        rs.Write(boundarybytes, 0, boundarybytes.Length);

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
        string header = string.Format(headerTemplate, paramName, new FileInfo(file).Name, contentType);
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
        rs.Write(headerbytes, 0, headerbytes.Length);

        FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
        byte[] buffer = new byte[4096];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
        {
            rs.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();

        byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
        rs.Write(trailer, 0, trailer.Length);
        rs.Close();

        WebResponse wresp = null;
        try
        {
            wresp = wr.GetResponse();
            Stream stream2 = wresp.GetResponseStream();
            StreamReader reader2 = new StreamReader(stream2);
        }
        catch (Exception ex)
        {
            if (wresp != null)
            {
                wresp.Close();
                wresp = null;
            }
        }
        finally
        {
            wr = null;
        }
    }
}

use it:

NameValueCollection nvc = new NameValueCollection();
//nvc.Add("id", "TTR");
nvc.Add("table_name", "uploadfile");
nvc.Add("commit", "uploadfile");
Post_File.HttpUploadFile("http://example/upload_file.php", @"C:\user\yourfile.docx", "uploadfile", "application/vnd.ms-excel", nvc);

example server upload_file.php:

m('File upload '.(@copy($_FILES['uploadfile']['tmp_name'],getcwd().'\\'.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
function m($msg) {
    echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
    echo $msg;
    echo '</div>';
}

I've been playing around a little bit and came up with a simplified, more generic solution:

private static string sendHttpRequest(string url, NameValueCollection values, NameValueCollection files = null)
{
    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
    // The first boundary
    byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
    // The last boundary
    byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
    // The first time it itereates, we need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick
    byte[] boundaryBytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");

    // Create the request and set parameters
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    request.Method = "POST";
    request.KeepAlive = true;
    request.Credentials = System.Net.CredentialCache.DefaultCredentials;

    // Get request stream
    Stream requestStream = request.GetRequestStream();

    foreach (string key in values.Keys)
    {
        // Write item to stream
        byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}", key, values[key]));
        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
        requestStream.Write(formItemBytes, 0, formItemBytes.Length);
    }

    if (files != null)
    { 
        foreach(string key in files.Keys)
        {
            if(File.Exists(files[key]))
            {
                int bytesRead = 0;
                byte[] buffer = new byte[2048];
                byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n", key, files[key]));
                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                requestStream.Write(formItemBytes, 0, formItemBytes.Length);

                using (FileStream fileStream = new FileStream(files[key], FileMode.Open, FileAccess.Read))
                {
                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        // Write file content to stream, byte by byte
                        requestStream.Write(buffer, 0, bytesRead);
                    }

                    fileStream.Close();
                }
            }
        }
    }

    // Write trailer and close stream
    requestStream.Write(trailer, 0, trailer.Length);
    requestStream.Close();

    using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
    {
        return reader.ReadToEnd();
    };
}

You can use it like this:

string fileLocation = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "somefile.jpg";
NameValueCollection values = new NameValueCollection();
NameValueCollection files = new NameValueCollection();
values.Add("firstName", "Alan");
files.Add("profilePicture", fileLocation);
sendHttpRequest("http://example.com/handler.php", values, files);

And in the PHP script you could handle data like this:

echo $_POST['firstName'];
$name = $_POST['firstName'];
$image = $_FILES['profilePicture'];
$ds = DIRECTORY_SEPARATOR;
move_uploaded_file($image['tmp_name'], realpath(dirname(__FILE__)) . $ds . "uploads" . $ds . $image['name']);

For people searching for 403 forbidden issue while trying to upload in multipart form the below might help as there is a case depending on the server configuration that you will get MULTIPART_STRICT_ERROR "!@eq 0" due to incorrect MultipartFormDataContent headers. Please note that both imagetag/filename variables include quotations (\") eg filename="\"myfile.png\"" .

    MultipartFormDataContent form = new MultipartFormDataContent();
    ByteArrayContent imageContent = new ByteArrayContent(fileBytes, 0, fileBytes.Length);
    imageContent.Headers.TryAddWithoutValidation("Content-Disposition", "form-data; name="+imagetag+"; filename="+filename);
    imageContent.Headers.TryAddWithoutValidation("Content-Type", "image / png");
    form.Add(imageContent, imagetag, filename);

hi guys after one day searching on web finally i solve problem with below source code hope to help you

    public UploadResult UploadFile(string  fileAddress)
    {
        HttpClient client = new HttpClient();

        MultipartFormDataContent form = new MultipartFormDataContent();
        HttpContent content = new StringContent("fileToUpload");
        form.Add(content, "fileToUpload");       
        var stream = new FileStream(fileAddress, FileMode.Open);            
        content = new StreamContent(stream);
        var fileName = 
        content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
        {
            Name = "name",
            FileName = Path.GetFileName(fileAddress),                 
        };
        form.Add(content);
        HttpResponseMessage response = null;          

        var url = new Uri("http://192.168.10.236:2000/api/Upload2");
        response = (client.PostAsync(url, form)).Result;          

    }

Here is multipart data post with basic authentication C#

public string UploadFilesToRemoteUrl(string url)
    {
        try
        {                             

            Dictionary<string, object> formFields = new Dictionary<string, object>();
            formFields.Add("requestid", "{\"id\":\"idvalue\"}");

            string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.ContentType = "multipart/form-data; boundary=" + boundary;

            // basic authentication.
            var username = "userid";
            var password = "password";

            string credidentials = username + ":" + password;
            var authorization = Convert.ToBase64String(Encoding.Default.GetBytes(credidentials));
            request.Headers["Authorization"] = "Basic " + authorization;

            request.Method = "POST";
            request.KeepAlive = true;

            Stream memStream = new System.IO.MemoryStream();
            WriteFormData(formFields, memStream, boundary);

            FileInfo fileToUpload = new FileInfo(@"filelocation with name");
            string fileFormKey = "file";
            if (fileToUpload != null)
            {
                WritefileToUpload(fileToUpload, memStream, boundary, fileFormKey);
            }
            request.ContentLength = memStream.Length;

            using (Stream requestStream = request.GetRequestStream())
            {
                memStream.Position = 0;
                byte[] tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);
                memStream.Close();
                requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            }

            using (var response = request.GetResponse())
            {
                Stream responseSReam = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseSReam);
                return streamReader.ReadToEnd();
            }
        }
        catch (WebException ex)
        {
            using (WebResponse response = ex.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse)response;
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                    return streamReader.ReadToEnd();

            }
        }
    }

    // write form id.
    public static void WriteFormData(Dictionary<string, object> dictionary, Stream stream, string mimeBoundary)
    {
        string formdataTemplate = "\r\n--" + mimeBoundary +
                                    "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
        if (dictionary != null)
        {
            foreach (string key in dictionary.Keys)
            {
                string formitem = string.Format(formdataTemplate, key, dictionary[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                stream.Write(formitembytes, 0, formitembytes.Length);
            }
        }
    }

    // write file.
    public static void WritefileToUpload(FileInfo file, Stream stream, string mimeBoundary, string formkey)
    {
        var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "\r\n");
        var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "--");

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                                "Content-Type: application/octet-stream\r\n\r\n";

        stream.Write(boundarybytes, 0, boundarybytes.Length);
        var header = string.Format(headerTemplate, formkey, file.Name);
        var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

        stream.Write(headerbytes, 0, headerbytes.Length);

        using (var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[1024];
            var bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                stream.Write(buffer, 0, bytesRead);
            }
        }
        stream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
    } 

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to post

How to post query parameters with Axios? How can I add raw data body to an axios request? HTTP POST with Json on Body - Flutter/Dart How do I POST XML data to a webservice with Postman? How to set header and options in axios? Redirecting to a page after submitting form in HTML How to post raw body data with curl? How do I make a https post in Node Js without any third party module? How to convert an object to JSON correctly in Angular 2 with TypeScript Postman: How to make multiple requests at the same time

Examples related to windows-phone-8

Microsoft Advertising SDK doesn't deliverer ads Calling async method on button click How to send a Post body in the HttpClient request in Windows Phone 8? Call asynchronous method in constructor? Install Visual Studio 2013 on Windows 7 How to post data using HttpClient? How to upload file to server with HTTP POST multipart/form-data? DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff") resulted in something like "09/14/2013 07.20.31.371" How to Deserialize JSON data? How to Install Windows Phone 8 SDK on Windows 7

Examples related to multipartform-data

How do I set multipart in axios with react? Send FormData with other field in AngularJS Send multipart/form-data files with angular using $http How to set up a Web API controller for multipart/form-data Upload a file to Amazon S3 with NodeJS File upload along with other object in Jersey restful web service Uploading file using POST request in Node.js Angularjs how to upload multipart form data and a file? Convert JS Object to form data Posting raw image data as multipart/form-data in curl