I am very new to file transfer between HttpClient
and a Web API, so please excuse any ignorance and guesswork in my code. I have been trying to post a file crea
As mentioned in the comments, your first problem was that the Stream
instances involved in the file copying were not being reset using Stream.Position = 0
. I know you've made these changes already, but I just want to emphasise that this is a two-part solution.
So, the second part:
In your example code, you've added the [DisableRequestSizeLimit]
annotation in order to bypass the default ASP.NET Core 2.0+ Kestrel request limits. However, there's also a limit that's imposed by IIS, which is 30MB by default. When this size limit is exceeded, IIS itself generates a 404 response, which is what you're seeing.
This answer explains how to change this limit using a custom Web.config
(included below for completeness):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<!-- 1 GB -->
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
As somewhat of a side note:
Unless you have a specific reason to do so, you can avoid the use of MemoryStream
in your code and just pass fs
directly into new StreamContent(...)
. You can do something similar with the Request.Body
stream and copy that directly into the output FileStream
. This would end up with:
public async Task PostDirAsync(string localDirPath, string serverDir)
{
var sourcePath = Path.Combine("Temp", Guid.NewGuid() + ".zip");
ZipFile.CreateFromDirectory(localDirPath, sourcePath, CompressionLevel.Fastest, true);
var streamContent = new StreamContent(File.Open(sourcePath, FileMode.Open));
streamContent.Headers.Add("Content-Type", "application/octet-stream");
var resp = await _client.PostAsync("api/File/PostDir?serverPath={WebUtility.UrlEncode(serverDir)}", streamContent);
}
And with:
[HttpPost("PostDir")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PostDir(string serverPath)
{
var zipName = Path.Combine(_config["QuickDrive:TempDir"], Guid.NewGuid() + ".zip");
using (var fileStream = System.IO.File.Create(zipName))
await Request.Body.CopyToAsync(fileStream );
return Ok();
}