Take an Httppostedfilebase and convert to Cloudfile (Azure Files) to avoid writing the File to the Server

Asked

Viewed 243 times

0

Good people, I have the following problem. The controller receives an Httppostedfilebase and sends it to Azure and for that I need to write to a temporary folder.

I would like to know a more elegant solution where you do not need to write on the Server disk. In short, send Httppostedfilebase directly to Azure with Cloudfile. Because this solution seems to me to be more performative, in case any ideas please share.

Follows code below:

 CloudStorageAccount _azureFile;

    public UploadArquivo()
    {
        _azureFile = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("azureFile"));
    }
    public void uploadArquivoAzure(HttpPostedFileBase arquivo, string caminhoArquivo)
    {
        //Escreve arquivo no caminho temporario
        arquivo.SaveAs(caminhoArquivo);

        // Criando o cliente do azure para acessar o storage
        CloudFileClient clienteArquivos = _azureFile.CreateCloudFileClient();

        // acessando o serviço de arquivos
        CloudFileShare compartilhamentoArquivos = clienteArquivos.GetShareReference("servicoArquivo");

        if (compartilhamentoArquivos.Exists())
        {
            // cria o diretorio raiz
            CloudFileDirectory dirRaiz = compartilhamentoArquivos.GetRootDirectoryReference();

            // criando o diretorio especifico
            CloudFileDirectory diretorio = dirRaiz.GetDirectoryReference("compartilhamentoArquivos");

            if (diretorio.Exists())
            {
                //Setando o arquivo e caminho do mesmo caminho do arquivo
                CloudFile arquivoEnviado = diretorio.GetFileReference(arquivo.FileName);


                arquivoEnviado.UploadFromFile(arquivo.);

                //arquivoEnviado.DownloadToFile(caminhoArquivo, FileMode.Create);

                //arquivoEnviado.UploadFromFile(caminhoArquivo);

            }
        }
    }

Any hint would help a lot.

1 answer

1

To keep your file in memory without having to write to the disk, you should write your file to a [System.IO.Stream.MemoryStream](https://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.110).aspx).

Would something like this:

[HttpPost]
[Route("upload")]
public async Task<IHttpActionResult> Upload()
{
    var uploaded = await GravarNaMemoriaAsync(arquivo.InputStream);
    // ...
    EnviarParaNuvem(arquivo.FileName, uploaded);
}

private async Task<Stream> GravarNaMemoriaAsync(Stream stream)
{
        // Verify that this is an HTML Form file upload request
    if (!Request.Content.IsMimeMultipartContent("form-data"))
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

    // Create a stream provider for setting up output streams that saves the output under memory
    var streamProvider = new MultipartMemoryStreamProvider();

    // Read the MIME multipart content using the stream provider we just created.
    var bodyparts = await Request.Content.ReadAsMultipartAsync(streamProvider);
    var documentStream = await streamProvider.Contents[0].ReadAsStreamAsync();

    var buffer = new byte[documentStream.Length];
    await documentStream.ReadAsync(buffer, 0, buffer.Length);

    return documentStream;
}

Now, about sending this one to Azure Storage, I believe you’re not doing it the right way. You are using disk file synchronization capabilities with the cloud storage area. Like you’re doing a "Onedrive" or "Dropbox," and that’s not really what I see you want to do.

If I understand correctly, you want to upload a file you uploaded to your application and store it in Azure Storage - and that is absolutely correct. But you must store it in the Blobs area, inside an Azure container.

For this, follows an example of starting:

private void EnviarParaNuvem(string meuArquivo, Stream memoryStream)
{
    // Recuperar sua conta de armazenamento via connection string.
    var storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));

    // Cria um client blob.
    var blobClient = storageAccount.CreateCloudBlobClient();

    // Cria uma referencia para um container criado anteriormente.
    var container = blobClient.GetContainerReference("mycontainer");

    // Cria uma referencia para um blob com nome de "meuArquivo".
    var blockBlob = container.GetBlockBlobReference(meuArquivo);

    // Cria ou sobrescreve o "meuArquivo" com o conteúdo do seu MemoryStream.
    blockBlob.UploadFromStream(memoryStream);
} 

Source: How to store Blob files in Azure.

  • First of all, thank you very much for your reply. In your example in the method "Gravarnamemoria" in tests the same is not returning content as stream, I see that you put a vector of bytes and do not use it, in analyzing the stream I see that you have a buffer, however I could not recover the same, could help in this case. As for using blob I haven’t quite figured out the big differences between blob and file, I’m studying to improve understanding and its placement already help a lot. Inclusive I’ve found File. Thank you.

  • @Napoleon Menezes, that’s correct. I changed the answer code with an excerpt of my old code. Some things were really missing.

  • @Napoleon Menezes, as for the difference between using Blob and File. File vc uses to synchronize a file on disk with the cloud, as if it were going to make a remote drive. In Blob you already hosting the file in a web/HTTP storage area. See it right, but I’m sure that’s what you need.

  • @Napoleon Menezes the answer solved his problem?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.