Reputation: 57
I still don't know very well about aws s3 storage, but I can already do the basic operations of listing / uploading / downloading objects using nuget awssdks.
However, when downloading an object, I have to create a file on my web server and then make the file available to my user.
It seems to me that I don't know how to perform the direct download to the client.
Is this possible ? If yes, which way to do this?
How to simply transform my current source code for direct download in S3 ?
Thank you very much for guidance.
private void DOWFile(string pFileDir, string pFileName, string pDescription)
{
//Armazena o path do arquivo
string lFilePath = pFileDir + pFileName;
//Verifica se o arquivo existe
if (File.Exists(lFilePath))
{
//Limpa o objeto de resposta
Response.Clear();
//Limpa o nome do arquivo
if (Request.UserAgent.Contains("Firefox")) pDescription = TFileInfo.CONVERTToFileName(pDescription);
//Adiciona o cabeçalho do donwload
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + HttpUtility.UrlPathEncode(pDescription) + "\"");
//Seta o tipo do arquivo
Response.ContentType = "application/octet-stream";
//Passa a referência do arquivo
Response.WriteFile(lFilePath);
//Executa o download do arquivo
Response.Flush();
//Finaliza o processamento
HttpContext.Current.Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
{
//Mostra a mensagem de Erro
SETErrorInfo(new TErrorInfo(-1, "DOWFile", TErrorInfo.ErrFileNotFound, "FileNotFound - " + lFilePath, false, true, false, true, false, TErrorInfo.TErrType.etLogic));
}
}
public bool FileDownS3(string pLocalPath, string pFileNameS3)
{
IAmazonS3 lClient_Aws = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
TransferUtility lUtility = new TransferUtility(lClient_Aws);
string filename = pLocalPath + pFileNameS3;
FileStream fs = File.Create(filename);
fs.Close();
lUtility.Download(filename, gBucketName, pFileNameS3);
return true;
}
Upvotes: 0
Views: 1750
Reputation: 23592
You need to return a File
object from your handler action, created from a MemoryStream
without saving it anywhere locally.
To do so, you first need to get the S3 object in the form of a MemoryStream
.
Pass the bucketName
& key
for your S3 object to AmazonS3Client.GetObjectAsync(...)
, which returns a response of type GetObjectResponse
.
GetObjectResponse
has a property called ResponseStream
.
This is a stream object which inherits from Amazon.S3.Model.StreamResponse
.
You can then copy this to a MemoryStream
:
GetObjectResponse response = await s3Client.GetObjectAsync(bucketName, keyName);
MemoryStream memoryStream = new MemoryStream();
using (Stream responseStream = response.ResponseStream)
responseStream.CopyTo(memoryStream);
}
Once copied, return converted to a File
in your controller action.
Make sure to also set a filename (third parameter to File(...)
so that the browser can determine the file type for the download:
public async Task<IActionResult> DownloadS3File() {
...
return File(memoryStream.ToArray(), "application/octet-stream", "filename.pdf");
}
This should trigger a download for an object downloaded from Amazon S3.
Upvotes: 1