Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

271
Views
Can save stream as local file, but when returning it as HttpResponseMessage - always empty file

I want to write export/download functionality for files from external API. I've created separate Action for it. Using external API I can get stream for that file. When I am saving that stream to local file, everything is fine, file isn't empty.

var exportedFile = await this.GetExportedFile(client, this.ReportId, this.WorkspaceId, export);

// Now you have the exported file stream ready to be used according to your specific needs
// For example, saving the file can be done as follows:
string pathOnDisk = @"D:\Temp\" + export.ReportName + exportedFile.FileSuffix;
                
using (var fileStream = File.Create(pathOnDisk))
{
    await exportedFile.FileStream.CopyToAsync(fileStream);
}

But when I return exportedFile object that contains in it stream and do next:

var result = await this._service.ExportReport(reportName, format, CancellationToken.None);

var fileResult = new HttpResponseMessage(HttpStatusCode.OK);
                
using (var ms = new MemoryStream())
{
    await result.FileStream.CopyToAsync(ms);
    ms.Position = 0;

    fileResult.Content = new ByteArrayContent(ms.GetBuffer());
}
            
fileResult.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                                                {
                                                    FileName = $"{reportName}{result.FileSuffix}"
                                                 };

fileResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

return fileResult;

Exported file is always empty.

Is it problem with stream or with code that try to return that stream as file?


Tried as @Nobody suggest to use ToArray

fileResult.Content = new ByteArrayContent(ms.ToArray());

the same result.


Also tried to use StreamContent

fileResult.Content = new StreamContent(result.FileStream);

still empty file.

But when I'm using StreamContent and MemmoryStream

using (var ms = new MemoryStream())
{
     await result.FileStream.CopyToAsync(ms);
     ms.Position = 0;

     fileResult.Content = new StreamContent(ms);
}

in result I got

{ "error": "no response from server" }


Note: from 3rd party API I get stream that is readonly.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

you used GetBuffer() to retrieve the data of the memory stream. The function you should use is ToArray() Please read the Remarks of the documentation of these functions.

https://docs.microsoft.com/en-us/dotnet/api/system.io.memorystream.getbuffer?view=net-6.0

using (var ms = new MemoryStream())
{
    ms.Position = 0;
    await result.FileStream.CopyToAsync(ms);

    fileResult.Content = new ByteArrayContent(ms.ToArray()); //ToArray() and not GetBuffer()
}
    
over 4 years ago · Santiago Trujillo Report

0

Your "mistake" although it's an obvious one is that you return a status message, but not the actual file itself (which is in it's own also a 200).

You return this:

var fileResult = new HttpResponseMessage(HttpStatusCode.OK);

So you're not sending a file, but a response message. What I'm missing in your code samples is the procedure call itself, but since you use a HttpResonseMessage I will assume it's rather like a normal Controller action. If that is the case you could respond in a different manner:

return new FileContentResult(byteArray, mimeType){ FileDownloadName = filename };

where byteArray is ofcourse just a byte[], the mimetype could be application/octet-stream (but I suggest you'd actually find the correct mimetype for the browser to act accordingly) and the filename is the filename you want the file to be named.

So, if you were to stitch above and my comment together you'd get this:

var exportedFile = await this.GetExportedFile(client, this.ReportId, this.WorkspaceId, export);

// Now you have the exported file stream ready to be used according to your specific needs
// For example, saving the file can be done as follows:
string pathOnDisk = @"D:\Temp\" + export.ReportName + exportedFile.FileSuffix;
                
using (var fileStream = File.Create(pathOnDisk))
{
    await exportedFile.FileStream.CopyToAsync(fileStream);
}

return new FileContentResult(System.IO.File.ReadAllBytes(pathOnDisk), "application/octet-stream") { FileDownloadName = export.ReportName + exportedFile.FileSuffix };

I suggest to try it, since you still report a 200 (and not a fileresult)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!