azurefile-uploadasp.net-mvc-5azure-blob-storageasp.net-mvc-views

How do I upload a file to Azure blob storage from a MVC view


I am coding a MVC5 internet application and would like some help to upload a file from my own filesystem to an Azure Blob.

Here is my Azure upload code function:

public void UploadFileToBlobStorage(string containerName, string blockBlogName, string fileName)
{
    // Retrieve storage account from connection string.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));

    // Create the blob client.
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // Retrieve reference to a previously created container.
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);

    // Create the container if it doesn't already exist.
    container.CreateIfNotExists();

    container.SetPermissions(
        new BlobContainerPermissions
        {
            PublicAccess =
                BlobContainerPublicAccessType.Blob
        }); 

    // Retrieve reference to a blob named "myblob".
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(blockBlogName);

    // Create or overwrite the "myblob" blob with contents from a local file.
    using (var fileStream = System.IO.File.OpenRead(fileName))
    {
        blockBlob.UploadFromStream(fileStream);
    }
}

Here is my function to upload a test file:

public void UploadTestFile(string localFileName)
{
    string containerName = "TestContainer";
    string blockBlogName = "Test.txt";
    AzureService azureService = new AzureService();
    azureService.UploadFileToBlobStorage(containerName, blockBlogName, localFileName);
}

I am not sure how to call the UploadTestFile() function from a MVC View where the user can browse to a file to upload.

Do I need to use Ajax, or can I simply upload a file by calling the method from a MVC view? Can I please have some help with this?

Thanks in advance


Solution

  • One way to call your UploadTestFile() function from an MVC View is by using the Html.BeginForm() method. I am including an example below:

    @using (Html.BeginForm("UploadTestFile", "INSERT_YOUR_CONTROLLER_NAME_HERE", FormMethod.Post, new { enctype = "multipart/form-data" })) {
        <span>
            <input type="file" name="myFile" multiple /> <br>
            <input type="submit" value="Upload" />
        </span>
    
    }
    

    Also, a couple of suggestions on your code:

    1. UploadFileToBlobStorage(): The code checks for container existence and setting permissions on every request. I would recommend separating the container.CreateIfNotExists() and container.SetPermissions(…) logic into a separate initialization function that needs to be executed only once on first deployment.

    2. UploadFileToBlobStorage(): It looks like the code will try to upload the localFileName from the VM file system and not the multi-part form data. One approach would be to use the HttpFileCollectionBase class and the Controller.Request property. Example below:

      public void UploadFileToBlobStorage(
          string containerName, 
          string blockBlogName, 
          HttpFileCollectionBase files) 
      {
      
          // .....
      
          // Use this:
          blockBlob.UploadFromStream(files[0].InputStream); 
      
          /* uploading the first file: 
             you can enumerate thru the files collection 
             if you are uploading multiple files */
      
          /* Instead of this: 
             Create or overwrite the "myblob" blob with contents 
             from a local file. */
          using (var fileStream = System.IO.File.OpenRead(fileName)) 
          {
              blockBlob.UploadFromStream(fileStream);
          }
      }
      
      [HttpPost]
      public void UploadTestFile() 
      {
          string containerName = "TestContainer";
          string blockBlogName = "Test.txt";
          AzureService azureService = new AzureService();
      
          // Notice the Request.Files instead of localFileName
          azureService.UploadFileToBlobStorage(
                containerName, blockBlogName, Request.Files);
      }
      

    Please let me know if that works on your end.