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

user3736648 picture user3736648 · Sep 17, 2014 · Viewed 9.8k times · Source

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

Answer

Perry Skountrianos - MSFT picture Perry Skountrianos - MSFT · Sep 19, 2014

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.