9

I am interested in porting some code to ASP.NET Core and wanted to know the most efficient way to send files, aka "download" files, from an ASP.NET Core web service.

With my old ASP.NET code, I was using a FileStream:

var content = new FileStream(
    myLocation,
    FileMode.Open, FileAccess.Read, FileShare.Read);

var result = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StreamContent(content)
};

However, I was trying to find the .NET equivalent of FreeBSD's sendfile() and found HttpResponse.TransmitFile . I assume this would be faster?

I am also concerned that the file will have to make an extra hop out of Kestrel, to IIS, before hitting the user. Any advice?

Brandon Petty
  • 605
  • 1
  • 6
  • 15
  • Where is the file located - file system or database? – Win Jul 07 '17 at 21:13
  • @Win, the file is located on the file system. – Brandon Petty Jul 07 '17 at 21:31
  • @BrandonPetty did you find a good performance solution? – Wahid Bitar Nov 14 '18 at 06:58
  • @Wahid, the project has been put on hold. I have not been able to look into this further. I am planning on letting the web server, not the web service, serve these files. I simply have to provide a custom auth / permission plugin. This also solves the problem of streaming content, requested in chunks, by multiple threads. This also avoids the extra hop if the service sits behind IIS, for example. I have not looked into how this would work with Azure storage. My needs were simply security based. – Brandon Petty Dec 20 '18 at 23:28
  • I would like to elaborate on my earlier comment. As stated before we are no longer sending files through our .net core api. I would recommend against it. Instead we are creating a Signed URL using a shared secret that points to an AWS S3 object. That URL can be used directly by the client to get the content. S3 authorizes the request based on the signature. – Brandon Petty Jan 07 '20 at 16:43

1 Answers1

13

If you mean streaming the file to the client, you can use the FileResult as your return type.

public FileResult DownloadFile(string id) {
    var content = new FileStream(myLocation,FileMode.Open, FileAccess.Read, FileShare.Read);
    var response = File(content, "application/octet-stream");//FileStreamResult
    return response;
} 

FileResult is the parent of all file related action results such as FileContentResult, FileStreamResult, VirtualFileResult, PhysicalFileResult. Refer to the ASP.NET Core ActionResult documentation.

Pradeep Kumar
  • 1,281
  • 7
  • 9
  • 5
    Unlike TransmitFile, this will buffer the file in memory, correct? That would make it slower? My understanding is that TransmitFile will write the file directly to the socket without buffering memory between kernel and user space much like SendFile on OSX/FreeBSD with C/C++. – Brandon Petty Jul 10 '17 at 15:47
  • 2
    Yes, it does. But there are better ways of handing it, There is nice blog which was very useful in my case https://blog.stephencleary.com/2016/11/streaming-zip-on-aspnet-core.html Hope that helps. – Pradeep Kumar Jul 12 '17 at 00:23