In MVC, we have used following code to download a file. In ASP.NET core, how to achieve this?
HttpResponse response = HttpContext.Current.Response;
Your controller should return an IActionResult
, and use the File
method, such as this:
[HttpGet("download")]
public IActionResult GetBlobDownload([FromQuery] string link)
{
var net = new System.Net.WebClient();
var data = net.DownloadData(link);
var content = new System.IO.MemoryStream(data);
var contentType = "APPLICATION/octet-stream";
var fileName = "something.bin";
return File(content, contentType, fileName);
}
my way is quite short and I think it suits most people's need.
[HttpPost]
public ActionResult Download(string filePath, string fileName)
{
var fileBytes = System.IO.File.ReadAllBytes(filePath);
new FileExtensionContentTypeProvider().TryGetContentType(Path.GetFileName(filePath), out var contentType);
return File(fileBytes, contentType ?? "application/octet-stream", fileName);
}
A relatively easy way to achieve this is to use the built-in PhysicalFile result, which is available to all controllers: MS Docs: PhysicalFile
A simple example:
public IActionResult DownloadFile(string filePath)
{
return PhysicalFile(filePath, MimeTypes.GetMimeType(filePath), Path.GetFileName(filePath));
}
Now of course you should never expose this kind of API, due to security concerns.
I typically shield the actual file paths behind a friendly identifier, which I then use to lookup the real file path (or return a 404 if an invalid ID was passed in), ie:
[HttpGet("download-file/{fileId}")]
public IActionResult DownloadFile(int fileId)
{
var filePath = GetFilePathFromId(fileId);
if (filePath == null) return NotFound();
return PhysicalFile(filePath, MimeTypes.GetMimeType(filePath), Path.GetFileName(filePath));
}
For those that are curious, the MimeTypes helper is a great little nuget package from the folks at MimeKit