Click here to Skip to main content
15,671,008 members
Please Sign up or sign in to vote.
0.00/5 (No votes)

How to send form-data using HttpWebRequest post method. Please check my code and advise me how to set request.ContentLength and pass formData to request.

for "x-www-form-urlencoded" content-type, I have used like.

Stream requestStream = request.GetRequestStream();
requestStream.Write(formData, 0, formData.Length);


What I have tried:

HttpWebRequest request;
HttpWebResponse response;
string filePath = HttpContext.Current.Server.MapPath("~/Uploads/test.pdf");            
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;            
MultipartFormDataContent formData = new MultipartFormDataContent();

// document content
formData.Add(new StringContent("Document Info"), "document");

// attachment content
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
formData.Add(new StreamContent(fileStream), "attachment");
// Create Request
request = (HttpWebRequest)WebRequest.Create(apiUrl);
request.KeepAlive = false;
request.Timeout = 180000;
request.Method = "POST";
request.ContentType = "application/form-data";
//request.ContentLength = ;
request.PreAuthenticate = true;
request.Accept = "application/json";

// Get Response
response = (HttpWebResponse)request.GetResponse();
Updated 24-Nov-22 4:08am

1 solution

HttpWebRequest is an extremely low-level API, so you have to build the multipart/form-data request yourself. There's an example of how to do that in this SO thread[^] - essentially:
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
request.ContentType = "multipart/form-data; boundary=" + boundary;

using (Stream rs = request.GetRequestStream())
    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, file, contentType);
    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
    rs.Write(headerbytes, 0, headerbytes.Length);

    using (FileStream fileStream = new FileStream(filePath, 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);

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

However, since your code uses the MultipartFormDataContent type, you already have a reference to the HttpClient class, which makes it much easier to upload files.
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
    formData.Add(new StringContent("Document Info"), "document");
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    formData.Add(new StreamContent(fileStream), "attachment");
    using (var response = await client.PostAsync(apiUrl, formData))
        // Read and process response.Content here...
NB: Bear in mind that creating a new HttpClient for every request in a long-running application can cause problems; it's better to use the IHttpClientFactory service:
You're using HttpClient wrong and it is destabilizing your software | ASP.NET Monsters[^]
You're (probably still) using HttpClient wrong...[^]
Make HTTP requests using IHttpClientFactory in ASP.NET Core | Microsoft Learn[^]
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900