How to uploaing large file(s) using ASP.NET Core

3 min readNov 18, 2022


Photo from:

We have a article that introduce how to upload file(s) via ASP.NET core’s API, you could refer the link. The story gonna to talk about how to handle uploading large file(s) [volume more than 2GB].

Uploading large volume data would be a little trick comparing to small data. First we have some limits on IIS/Kestrel for the .NET MVC framework. By default we merely only have volume 28.6MB per request. If you try to exceed the limit and you will return http status code: 413 [Payload too large]. For the IIS, we could modify web.config to release the limit (maxAllowedContentLength). And for the Kestrel, we need to configure both MaxReqeustBodySize and MultipartBodyLengthLimit to release more volume for us.

Second, we might have two approach to deal with file uploading. We have demonstrated from my previous article using buffering (via IFormFile). But for the larger file(s) we might not take advantage of buffering and might exhaust our resource (memory/disk) easily. So using streaming (via MultipartReader) way would be reasonable to handle the case.

This story we modified our uploading API using streaming approach to deal the large volume file(s). We started from the client side which will submit a request to API:

Client — Side

Below was the real sample of http post request that using multipart/form-data for carrying file(s) content:

POST https://localhost:5001/devwfapi/api/form/uploadattachmentsonfly
45.84 s

POST /devwfapi/api/form/uploadattachmentsonfly HTTP/1.1
System: xxxxxxxx
AccessToken: ALwzpK59onuqtvZVTOEsMYbUSPAB-xVGc22RqCh8z0Y8HHkKV_w3MLmKnJE_ywj_Aw==
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: 9edc5eb6-0397-4520-a03a-13212d1b6996
Host: localhost:5001
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------156313382635509050530525
Content-Length: 444312365

Content-Disposition: form-data; name="subDirectory"
Content-Disposition: form-data; name="files"; filename=""
Content-Disposition: form-data; name="files"; filename="InstallDivvy.exe"
Content-Disposition: form-data; name="files"; filename="PowerToysSetup-0.64.0-x64.exe"
Content-Disposition: form-data; name="files"; filename="2022 Scrum Sharing PPT.pdf"
<2022 Scrum Sharing PPT.pdf>
Content-Disposition: form-data; name="files"; filename="VSCodeUserSetup-x64-1.72.2.exe"

You should take note of the structure under the section “Content-Length”. Cause we won’t rely on the IFormFile (buffering model binding) anymore. For the MultipartReader (streaming), we need to parse the content section by ours own.

Next, we will demonstrate how to using MultiparReader over API side. But first we need to finish the help class as below:

One thing need to mention, if your file API was open to public then you must care more about the security and virus of potential threat might occurred.

The final part we are going to finish our file API for the function of uploading:

We have did a little tricky for passing the sub-directory path to the API. you could find out that we add our “subdirectory” string on the top of content (inside MultipartFormDataContent). Then we could retrieve back on the API side for the first section.

For the rest, we just fire a uploading request to our file API and we also comparing Buffering VS Streaming for uploading same volumes of files under the local testing environment. Not really surprised us that streaming approach take advantage for handling larger file(s).

Buffering (IFromFile)
Streaming (MultipartReader)





Coding for fun. (Either you are running for food or running for being food.)