Upload Any File Using HTTP Post Multipart Form Data

In this article, we will discuss how to upload any file using HTTP Post multipart/ form-data in C#. I have tried my best to explain the use of the code needed for multipart/form-data posts many times while working with APIs in C#. I hope this will be helpful in situations where we need to upload any file or image to the server using the post method in C#.


There might be a situation that you will have to write code to post your file to the server through C# code without using any HTML form page. Suppose you have some images on your server and you want to post those to any third-party API through the C# application. You can achieve that through the following code.

Here are the steps to be followed.

Step 1

Create a new application in .NET, it could be either web or console application according to your requirement. Skip this step if you want to use  the existing project. 

Step 2

Create a new class with the following code. You can create this class at any common place from where you can access it easily. 

public static class FormUpload  
    private static readonly Encoding encoding = Encoding.UTF8;  
    public static HttpWebResponse  MultipartFormPost(string postUrl, string userAgent, Dictionary<string, object> postParameters, string headerkey, string headervalue)  
        string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());  
        string contentType = "multipart/form-data; boundary=" + formDataBoundary;  

        byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);  

        return PostForm(postUrl, userAgent, contentType, formData, headerkey, headervalue);  
    private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData, string headerkey, string headervalue)  
        HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;  

        if (request == null)  
            throw new NullReferenceException("request is not a http request");  

        // Set up the request properties.  
        request.Method = "POST";  
        request.ContentType = contentType;  
        request.UserAgent = userAgent;  
        request.CookieContainer = new CookieContainer();  
        request.ContentLength = formData.Length;  

        // You could add authentication here as well if needed:  
        // request.PreAuthenticate = true;  
        // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;  

        //Add header if needed  
        request.Headers.Add(headerkey, headervalue);  

        // Send the form data to the request.  
        using (Stream requestStream = request.GetRequestStream())  
            requestStream.Write(formData, 0, formData.Length);  

        return request.GetResponse() as HttpWebResponse;  

    private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)  
        Stream formDataStream = new System.IO.MemoryStream();  
        bool needsCLRF = false;  

        foreach (var param in postParameters)  
            if (needsCLRF)  
                formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));  

            needsCLRF = true;  

            if (param.Value is FileParameter) // to check if parameter if of file type   
                FileParameter fileToUpload = (FileParameter)param.Value;  

                // Add just the first part of this param, since we will write the file data directly to the Stream  
                string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",  
                    fileToUpload.FileName ?? param.Key,  
                    fileToUpload.ContentType ?? "application/octet-stream");  

                formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));
                // Write the file data directly to the Stream, rather than serializing it to a string.  
                formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);  
                string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",  
                formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));  

        // Add the end of the request.  Start with a newline  
        string footer = "\r\n--" + boundary + "--\r\n";  
        formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));  

        // Dump the Stream into a byte[]  
        formDataStream.Position = 0;  
        byte[] formData = new byte[formDataStream.Length];  
        formDataStream.Read(formData, 0, formData.Length);  

        return formData;  

    public class FileParameter  
        public byte[] File { get; set; }  
        public string FileName { get; set; }  
        public string ContentType { get; set; }  
        public FileParameter(byte[] file) : this(file, null) { }  
        public FileParameter(byte[] file, string filename) : this(file, filename, null) { }  
        public FileParameter(byte[] file, string filename, string contenttype)  
            File = file;  
            FileName = filename;  
            ContentType = contenttype;  

In this class, we have three methods.


This method has five parameters. You can increase/decrease the number of parameters according to your requirement. These five parameters are, 

  • Posturl 
    This must be the url to which you want to post the form.
  • userAgent
    This is up to your requirement; if needed, then pass the value as required.
  • postParameters
    This is of type Dictionary. You can pass the parameter name and value as “key-value”
  • headerkey
    This must be the name of the header that needs to be passed. In this example, I have used it as a string which can be used to pass a single header. If the header is not required, you can ignore this parameter.
  • headervalue
    This must be the value of the header to be passed.

If your request requires multiple headers you can use Dictionary for the header as we used for parameters. In that case, instead of headerkey and headervalue parameters, you will have to use a single parameter of type Dictionary.

Ex- Dictionary<string,string> Headers

Here header name and value will be passed as a key-value pair.


This method will give you form data in byte form to post. 


This is a private method and will be called within the public method, MultipartFormPost. This method has two other parameters, contentType and formData. We have added static content type while we got formData from GetMultipartFormData. 

I have also created a class named FileParameter with some class members and constructor to use directly while passing a file as a parameter to my post method.

Step 3

Write the below code section from where you want to call the multipart-post method. The code line byte[] bytes = wc.DownloadData(fileName); is used to download the file if your file is on the server otherwise you can convert that file directly to bytes if it exists locally. I have passed a parameter named “fileToUpload”, this is of type class FileParameter. You can pass the name and number of parameters according to your requirement.

try {  
    string requestURL = ”your url to post”;  
    string fileName = ”URL of your file”  
    WebClient wc = new WebClient();  
    byte[] bytes = wc.DownloadData(fileName); // You need to do this download if your file is on any other server otherwise you can convert that file directly to bytes  
    Dictionary < string, object > postParameters = new Dictionary < string, object > ();  
    // Add your parameters here  
    postParameters.Add("fileToUpload", new FormUpload.FileParameter(bytes, Path.GetFileName(fileName), "image/png"));  
    string userAgent = "Someone";  
    HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(requestURL, userAgent, postParameters, headerkey, headervalue);  
    // Process response  
    StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());  
    returnResponseText = responseReader.ReadToEnd();  
} catch (Exception exp) {}