Upload files with HTTPWebrequest multipart/form-data
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Uploading a file with HttpWebRequest and multipart/form-data means building the HTTP body exactly the way a browser would send a form containing a file input. The approach still matters in older .NET Framework code, but for new projects HttpClient is usually simpler, so this pattern is mainly for maintaining or understanding legacy code.
Understand the Multipart Structure
A multipart/form-data request body is split into parts separated by a boundary string. Each part has headers such as Content-Disposition, and file parts usually also include a Content-Type header.
The request must end with a closing boundary. If the boundary format is wrong, many servers will treat the body as malformed even though the raw bytes were sent successfully.
Build the Request Carefully
The core steps are:
- create a boundary string
- set
ContentTypetomultipart/form-data; boundary=... - write form fields and file bytes to the request stream
- write the closing boundary
- read the response
Here is a complete example in C#.
This example uploads one file. The same pattern can be extended to include ordinary form fields before the file part.
Add Text Fields When the API Requires Them
Many upload endpoints need metadata alongside the file, such as a title, token, or folder ID. Those values are just additional multipart sections.
Write that part to the stream before the file part, using the same boundary format.
Stream Large Files Instead of Reading Everything at Once
File.ReadAllBytes is easy to understand, but it loads the full file into memory. For large uploads, stream the file in chunks.
That reduces peak memory usage and is the better pattern for large files or high-throughput upload code.
Prefer HttpClient for New Code
HttpWebRequest still works, but it is older and more verbose than current .NET networking APIs. In new applications, HttpClient with MultipartFormDataContent is usually clearer and less error-prone.
This matters because many multipart bugs in legacy code are not business-logic bugs at all. They are manual request-formatting mistakes that newer APIs avoid.
Common Pitfalls
The most common mistake is formatting the boundary incorrectly or forgetting the closing boundary line.
Another mistake is omitting the required \r\n separators between multipart headers and content.
A third issue is reading the entire file into memory for large uploads when a stream-based approach would be safer.
Finally, some APIs require authentication headers or specific field names. If the server rejects the request, verify the endpoint contract before rewriting the multipart code.
Summary
- '
multipart/form-datauploads require correctly formatted boundaries, headers, and separators.' - With
HttpWebRequest, you manually write each multipart section to the request stream. - Add form fields as separate parts using the same boundary format.
- Stream large files instead of loading them fully into memory when possible.
- Use
HttpClientfor new code, but understandHttpWebRequestfor legacy maintenance. - If an upload fails, inspect boundary formatting, field names, and server requirements first.

